Change Specific Line of a File

Hi everyone,

I am attempting to do something that should be very simple. How do I replace a specific line of a file with different text, and then save that file to its original name? I believe I want to use the sed command with the c option, but I after trying many times, I can't get the right syntax. I am using bash.

Mike

different_text="this is the new text"
awk -v diff="$different_text" '{ if(NR==4) { print diff}
                              else {print $0} } ' filename > newfilename
sed '42c\'"I am the walrus" file >newfile

Hi,

Yes I was trying to something similar. However, that still does not work. Is that the syntax for bash?

Works here, Ubuntu 7.something, bash 3.2.13. The sed version is what decides whether it works or not, though. I have GNU sed version 4.1.5

vnix$ sed '4c\'"I am the walrus" /etc/motd
Linux left 2.6.20-17-386 #2 Thu Jul 10 00:02:05 UTC 2008 i686

The programs included with the Ubuntu system are free software;
I am the walrus
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

Try putting the change on a different line:

sed '42c\
I am the walrus' file >newfile

Yes, you would put a backslash and a newline between "42c" and "I am the walrus". Yes, that's right. No, I'm not kidding. (Nothing personal, it's just that the normal reaction to this instruction is "I tried it and it doesn't work." "So did you put a backslash and a newline between the two lines?" "No, was I supposed to?")

Perhaps i am not going about this correctly. Here is my "test file":

$cat test.txt
coo
coo
ca
choo
$

Let's say I simply want to replace the first line (coo) with koo.

With the above suggestion:

$sed '1c\'"koo" test.txt
sed: 1: "1c\koo": extra characters after \ at the end of c command

Putting a space before "koo" yields:

$sed '1c\' "koo" test.txt
sed: koo: No such file or directory
coo
ca
choo

I get closer by typing:

$sed '1c\
> koo' test.txt
koocoo
ca
choo

But it's still not right. I am using the bash that comes with OS X Leopard. Any ideas on what's going wrong?

Probably your version of sed is different; OSX is traditionally BSD based.

Try this:

sed '1c\
koo\
' test.txt

Yes that works. Thank you very much. Any idea why it can't all be on one line?

My limited experience of BSD sed is that it's a bit crude. Then on the other hand at one point it was pretty much the best definition of a standard.

Anyhow, to just avoid this whole syntactic morass, maybe it would be better (albeit marginally less efficient) to just use the following instead:

sed '42s/.*/I am the walrus/' file

That should basically work everywhere without modification.

The "c" command is part of POSIX sed.

Anytime you refer to GNU sed or GNU awk or GNU date you get nifty, new and non-standard ways of doing things. era's first example is pretty much GNU-only, the "two-line" thing is actually the old-fashioned standard. (see Dougherty & Robbins 'sed & awk' book) Meaning it is portable. If you work only on ubuntu or redhat you have GNU-derived tools. If you are on HPUX probably not.

It doesn't make anything here right or wrong, merely confusing for new people.
The authoritative answer is the man page on your machine.

The main portability hurdle here is whether or not c adds a trailing newline after the new text. It seems odd to me that it doesn't, but anyway, if you can't know, you'd better avoid the whole construct, or accept the fact that your script is specific to a particular class of sed implementations. But that way lies madness ...