Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BSD sed: extra characters at the end of d command

Tags:

sed

bsd

I use sed command on mac OS, following is the text.

$ cat pets.txt 
This is my cat
  my cat's name is betty
This is your dog
  your dog's name is frank
This is your fish
  your fish's name is george
This is my goat
  my goat's name is adam

when I run: (BSD sed)

$ sed '3,6 {/This/d}' pets.txt

It show error:

sed: 1: "3,6 {/This/d}": extra characters at the end of d command

what's wrong with it? when I use gsed(GNU sed), it works well.

like image 642
lutaoact Avatar asked Sep 28 '14 03:09

lutaoact


3 Answers

For anyone who found this question due to a similar error message, but caused by an attempt to in-place edit on Mac OS X

As per https://github.com/lmquang/til/issues/18:

OS X requires the extension to be explicitly specified. The workaround is to set an empty string:

$ sed -i '' 's/megatron/pony/g' /path/to/file.txt

         ^^

man sed:

-i extension

Edit files in-place, saving backups with the specified extension. If a zero-length extension is given, no backup will be saved. It is not recommended to give a zero-length extension when in-place editing files, as you risk corruption or partial content in situations where disk space is exhausted, etc.

So, there seems to be an issue on Mac OS X when extension is omitted, and so you have to supply -i with an empty string ('').

See also https://unix.stackexchange.com/a/112024/23614:

If using FreeBSD or OS/X, replace -i with -i ''.

like image 86
user664833 Avatar answered Dec 02 '22 20:12

user664833


The simplest solution is to put a semi-colon after the d (the spaces shown are optional):

sed -e '3,6 { /This/d; }' pets.txt

BSD sed is fussier about the layout than GNU sed. There are a number of GNU extensions that are not part of BSD sed, and this is one. The semi-colon isn't the universal solution to problems, though it does solve many of them. You could also spread the commands out over multiple lines, or put them in multiple -e options, or various other 'tricks'.

like image 44
Jonathan Leffler Avatar answered Dec 02 '22 20:12

Jonathan Leffler


You're relying on the GNU extension which lets { and } be part of a single expression. To make it portable, you need to ugly it up a bit:

sed -e 3,6{ -e /This/d -e } pets.txt

You could also put the commands into a file, one per line:

3,6 {
  /This/d
}

For more on why this is, see here: https://unix.stackexchange.com/questions/13711/differences-between-sed-on-mac-osx-and-other-standard-sed

like image 20
John Zwinck Avatar answered Dec 02 '22 19:12

John Zwinck