tags:

views:

130

answers:

5
$ cat file.txt
one
two
three
$ cat file.txt | sed "s/one/1/"
1
two

Where is the word "three"?

UPDATED: There is no line after the word "three".

+1  A: 

I guess there is no new line character after last line. sed didn't find line separator after last line and ignore it.

Update

I suggest you to rewrite this in perl (if you have it installed):

cat file.txt | perl -pe 's/one/1/'
Ivan Nevostruev
You are correct - there is no new line character. But I cannot control this file - new line can be at the end but someone can remove it. And I need to process both of these cases.
Vladimir Bezugliy
It should work either way.
Wooble
That was my guess, too, but I just tested it on a file that had no line separator at the end -- the second E of THREE was the last character in the file -- and my version of sed dealt with it just fine. I'm using GNU sed version 4.1.5
shoover
@Wooble But it does not work :(
Vladimir Bezugliy
@shoover I use sed from AIX 5.3
Vladimir Bezugliy
@Vladimir `perl` should fix it. If you can use it. See update
Ivan Nevostruev
Unfortunately I cannot use perl.
Vladimir Bezugliy
+2  A: 

As Ivan suggested, your text file is missing the end of line (EOL) marker on the final line. Since that's not present, three is printed out by sed but then immediately over-written by your prompt. You can see it if you force an extra line to be printed.

sed 's/one/1/' file.txt && echo

This is a common problem since people incorrectly think of the EOL as an indication that there's a following line (which is why it's commonly called a "newline") and not as an indication that the current line has ended.

jamessan
I need something like "sed 's/one/1/' file.txt > newfile.txt". But it does not work with "echo".
Vladimir Bezugliy
That should work just fine. Sed's still printing out the `three` line. You just don't see it when you run interactively because of the prompt. Since it's still being printed out, redirecting to a file means the newfile will have that line.
jamessan
Vladimir Bezugliy
No, the echo was just for demonstration purposes. It forced a blank line to be printed when you ran the command interactively in order to separate the `three` line from your prompt but it has no bearing on how sed actually works. After running `sed 's/one/1/' file.txt > new_file.txt`, just open new_file.txt with your editor. You should see all three lines.
jamessan
A: 

Instead of cat'ing the file and piping into sed, run sed with the file name as an argument after the substitution string, like so:

sed "s/one/1/" file.txt

When I did it this way, I got the "three" immediately following by the prompt:

1
two
three$
GreenMatt
+1  A: 

A google search shows that the man page for some versions of sed (not the GNU or BSD versions, which work as you'd expect) indicate that it won't process an incomplete line (one that's not newline-terminated) at the end of a file. The solution is to ensure your files end with a newline, install GNU sed, or use awk or perl instead.

Wooble
A: 

here's an awk solution

awk '{gsub("one","1")}1' file.txt
ghostdog74