0

This is a question regards to sed on Mac, which requires a zero-length string for in-place replacement without backup files.

#!/usr/bin/env bash -x

SEDOPT='-i "" '
echo $SEDOPT
sed $SEDOPT -e "s/a/a/g" filename.txt
sed "$SEDOPT" -e "s/a/a/g" filename.txt
sed -i "" -e "s/a/a/g" filename.txt

If you execute the above commands, you will get the output like

1|+ SEDOPT='-i "" '
2|+ echo -i '""'
3|-i ""
4|+ sed -i '""' -e s/a/a/g filename.txt
5|+ sed '-i "" ' -e s/a/a/g filename.txt
6|+ sed -i '' -e s/a/a/g filename.txt

I'm setting up a sed option variable SEDOPT, that will be changed depends distro.

Can someone help me on make the output of line 4 and 5 behave like line 6? Thank you.

Alan Dong
  • 3,981
  • 38
  • 35

1 Answers1

2

Quotes do not nest the way you are expecting them to. Use an array to store arguments.

SEDOPT=( -i "" )
sed "${SEDOPT[@]}" -e "s/a/a/g" filename.txt

With the line

sed -i "" ...

the first two arguments to sed are -i and the empty string; bash removes the double quotes during the quote removal phase of its evaluation of the command line.

With the code

SEDOPT='-i ""'
sed $SEDOPT ...

the variable SEDOPT expands to a string containing a literal whitespace and two double quotation marks. The result is subject to word splitting (where the whitespace is removed, leaving two separate words -i and "" in place of the original string -i ""), but not quote removal, so the literal string "" is passed to sed as the second argument.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thank you, this bugged me for two days. I was being an amateur not thinking to use array to pass arguments. – Alan Dong Oct 27 '15 at 19:19