Why does sed behave differently in a shell script?

2019-05-09 20:45发布

问题:

Why does sed behave differently depending upon whether it's run from the command line or a shell script? Here's a basic example:

$ cat test.txt
foo
bar
baz

$ sed -e 's/^b\(\w*\)$/q\1/g' test.txt # works as intended
foo
qar
qaz

$ cat test.sh # The exact same command
sed -e 's/^b\(\w*\)$/q\1/g' test.txt

$ bash test.sh
foo
bar
baz

Now, as I look into this further, \w isn't a standard BRE or ERE (even with the -E flag) character class in POSIX regexes. It's these sorts of Perl-like GNU extensions to REs that don't work when I run the command from a shell script. Indeed, if I change \w to the POSIX [[:alnum:]] it works as I intend. No GNU extensions seem to work from the shell script (including uppercase/lowercase \U and \L). So does sed try to detect if it's running from a shell script and enter some sort of strict POSIX-only mode? Is there documentation about this? Can I disable this behavior?

(This is gsed (GNU sed) 4.2.2)

回答1:

The issue was simply that I had a long-forgotten bash alias changing sed to gsed — the GNU version as installed by Homebrew. That explains why sed --version reported itself as gsed at the command line. I had checked which sed from both the script and the prompt, but I didn't think about type and bash aliases.

$ type sed
sed is aliased to `gsed'


标签: shell sed