I have text that goes like this:

I am happy. I am here. How are you, Meg? 

I want this to be:

I am happy.
I am here.
How are you, Meg? 

For full stops I tried

tr -s '. ' '\n' <file.txt >out.txt

But it's not working.


As far as I know tr only works with single characters and ". " is a string not a character, so it is possible to do what you want by using sed or awk, for example:

sed -e "s/\. /\n/g" file.txt > out.txt
  • He said use tr. – argle Jan 3 '17 at 12:11
  • 9
    @argle Well, he can't. – Kusalananda Jan 3 '17 at 12:16
  • 2
    I know. I just didn't realize xy answers were allowed even against explicit constraints. This could have been my answer. So I was protesting. :P – argle Jan 3 '17 at 12:25

You don't. tr is not designed for that. It's designed to transliterate a set of single characters into another set of single characters, e.g., A-Z into a-z. Using tr with .␣ (a dot and a space) and \n will replace all dots and spaces with newlines.

Use (GNU) sed instead:

$ echo 'I am happy. I am here. How are you, Meg?' | sed 's/\([!.?]\) /\1\n/g'
I am happy.      
I am here.       
How are you, Meg?

The sed editing script here will replace all occurrences of !, . or ? that are followed by a space, by the same character and a newline.

  • 1
    I'd like to emphasize single characters since OP seems to believe tr will replace TWO characters '. ' with just one character '\n' - Instead tr replaces both '.' and ' ' with '\n'. – ihato Jan 3 '17 at 12:46
  • @Yanevski Emphasis added. – Kusalananda Jan 3 '17 at 12:57

As has been mentioned , you can't achieve what you want with tr due to the nature of tr. But there are many other alternatives. For instance, Python 2.

As one-liner we could do this:

python -c "import sys;print '\n'.join([ j.strip() for l in sys.stdin.readlines() for j in  l.rstrip().split('.')])" < input.txt

As a script , it would be like so:

#!/usr/bin/env python
import sys

sentences = []
for line in sys.stdin:
    for sentence in line.rstrip().split('.'):

print "\n".join(sentences)

And used as so:

$ ./split_to_lines.py  < input.txt                                                                    
I am happy
I am here
How are you, Meg?

Nothing particularly complex is going on here - we're merely splitting all lines in file into sentences at . and then strip leading and trailing space for each sentence. All that goes into a list, which is then reassembled via .join() function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy