Matt B. Matt B. - 1 month ago 7
Bash Question

Why does sed behave differently in a shell script?

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
)

Answer

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'