Re: [List] Re: Nice easy sed question
- Reply: Arthur Chance : "Re: [List] Re: Nice easy sed question"
- Reply: Bob Proulx : "Re: [List] Re: Nice easy sed question"
- In reply to: Bob Proulx : "Re: Nice easy sed question"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 12 Sep 2025 09:58:42 UTC
This is a reply to several including Bob, Sad and Kyle. TLDR: The methods and syntax I was using are fine on GNU sed but BSD sed appears to require a newline and there's no way around it. And we all seem to agree that the documentation isn't the best. On 12/09/2025 07:04, Bob Proulx wrote: > Frank Leonhardt wrote: >> I've got a file called example.txt: >> >> Line 1 >> Line 2 >> Line 3 >> >> I'm trying to add "New Line" after "Line 2" > Okay. > >> Both of these should work as far as I know: >> >> sed -i.bak '/Line 2/a\New Line' example.txt > That \N is not valid syntax. > >> sed -i.bak -e '/Line 2/a\" -e "New Line' example.txt > That \" is not valid syntax. > >> (BSD requires a backup specification for -i IIRC, or '') > Yes. An annoying choice! Perl pioneered the syntax and being first > at doing so and it being adequate everyone else should have followed > for consistency. > >> If I run it with the -i and have a genuine newline after \ it does write the >> correct stuff to stdout: >> >> # sed '/Line 2/a\ >>> New Line' example.txt >> Line 1 >> Line 2 >> New Line >> Line 3 > Yes. The \ must be followed by a newline. You have the correct syntax. > >> With an -i in any variations of the first two (single command or two -e -e) >> I just get errors like: >> >> ": invalid command code e >> ": extra characters at the end of N command >> ": extra characters after \ at the end of a command >> >> (All starting with " - why?) > Works for me. Here is an example. > > rwp@mayhem:~$ sed -i.bak '/Line 2/a\ > New Line' foo1 > rwp@mayhem:~$ cat foo1 > Line 1 > Line 2 > New Line > Line 3 > > And with use of -e for two different expressions works too. > > rwp@mayhem:~$ sed -i.bak -e '/^Line 2/a\ > New Line' -e 's/3/4/' foo1 > rwp@mayhem:~$ cat foo1 > Line 1 > Line 2 > New Line > Line 4 > > What is the exact command you are having trouble with? > >> The only way I can make it work is with -i.bak and on two lines (as above). > The newline after the \ backslash is required. That is the correct syntax. > >> The Fine Manual says of 'a': >> >> [1addr]a\ >> text Write text to standard output immediately before each attempt to >> read a line of input, whether by executing the “N” function or by >> beginning a new cycle. > The manual was written by people who already knew how it worked. The > newline after the backslash is as far as I know always required. The > behavior is based upon the ed feature. > > man ed > (.)a Append text to the buffer after the addressed line. Text is > entered in input mode. The current address is set to last line > entered. > > Here is an ed example. > > rwp@mayhem:~$ ed -s foo1 <<EOF > /^Line 2/a > New line > . > w > q > EOF > rwp@mayhem:~$ cat foo1 > Line 1 > Line 2 > New line > Line 3 > >> This implies the newline is required but I'm struggling with finding a sane >> syntax here. A pointer to some better documentation would be welcome! > This confuses me because you have a working example using sed and it works. > >> Or is there a better utility for editing (non-system) configuration files by >> script I just don't know about? > That depends upon many things. What file is being edited? Is it an > INI file? A CSV? Would a tool like Puppet, Chef, Salt, Ansible be > better? Perl is powerful and a good general purpose batch editing > choice. Perhaps ed is the best answer. Any recommendation without > information would just be a guess in the dark. > > I personally like sed and most often use sed to automate edit files. > I always use it in combination with grep to look to see if the file > needs to be edited first in order to make the sequence idempotent such > that files are not always being touched if there is no reason to touch > them. Because having files updated all of the time falsely points > fingers at them when there are problems. > > Bob Thanks Bob, et al. I was suspecting the newline was the issue. However the following do work perfectly correctly on GNU sed. sed -i.bak '/Line 2/a\New Line' example.txt sed -i.bak -e '/Line 2/a\' -e 'New Line' example.txt (I used mismatched quotes in the email when typingoriginally, but the correct way around on the command line). I think I've finally found something that Linux does better - it took long enough :-) If BSD sed really is that particular about there being a newline, which IMHO is really clunky in a script, then that's what I'll have to do - and put a wrapper around it so it doesn't offend my sensibilities! @ Sad Clouds Yes, awk. I've been meaning to make friends with awk since System V. I've just found other ways of doing things in the mean time. On 12/09/2025 01:19, Kyle Evans wrote: > The synopsis and usage string don't seem to be based in reality all > the way back to BSD 4.4 Lite, > the original usage here is technically fine. > > Thanks, > > Kyle Evans Yes, exactly! I've sanity checked things in Kernighan and Pike, which is a lot better than the man page but all their examples centre on the 's' command. Thanks, Frank.