为什么 sed 在 shell 脚本中表现不同? [英] Why does sed behave differently in a shell script?
问题描述
为什么 sed 的行为取决于它是从命令行还是从 shell 脚本运行?这是一个基本示例:
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
现在,当我进一步研究时,\w
不是 POSIX 正则表达式中的标准 BRE 或 ERE(即使带有 -E
标志)字符类.当我从 shell 脚本运行命令时,这些类似于 Perl 的 GNU 对 RE 的扩展不起作用.实际上,如果我将 \w
更改为 POSIX [[:alnum:]]
它会按我的意图工作.似乎没有 GNU 扩展可以从 shell 脚本(包括大写/小写 \U
和 \L
)工作.那么 sed
是否尝试检测它是否从 shell 脚本运行并进入某种严格的 POSIX-only 模式?有关于这方面的文件吗?我可以禁用此行为吗?
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?
(这是 gsed (GNU sed) 4.2.2
)
推荐答案
问题只是我有一个久违的 bash 别名将 sed
更改为 gsed
—Homebrew 安装的 GNU 版本.这就解释了为什么 sed --version
在命令行中将自己报告为 gsed
.我已经从脚本和提示中检查了 which sed
,但我没有考虑 type
和 bash 别名.
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'
这篇关于为什么 sed 在 shell 脚本中表现不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!