试图找到 this sed question 的答案时 我想到了一个我无法理解的奇怪行为。
假设我有一个名为 data
$> cat data
foo.png
abCd.png
bar.png
baZ.png
任务是在行中使用 sed 将所有具有大写 ASCII 字符的行替换为小写。所以输出应该是:
$> cat data
foo.png
abcd.png
bar.png
baz.png
该解决方案应该在非 gnu sed 上也能像 Mac 上的 sed 一样工作
我尝试将这个嵌入式 awk 嵌入到 sed 的替换部分:
sed -E 's/[^ ]*[A-Z][^ ]*.png/'$(echo \&|awk '{printf("<%s>[%s]",$0, tolower($0))}')'/' data
奇怪的是,输出是这样的:
foo.png
<abCd.png>[abCd.png]
bar.png
<baZ.png>[baZ.png]
正如您所看到的,sed 正在使用大写字母选择正确的行,这也影响到 awk,但是 awk 的 tolower()
函数失败并生成与输入相同的文本。
请 shell 专家解释一下这种奇怪的行为。
最佳答案
你的 awk
命令在 sed
之前运行命令,而不是 sed
的子进程命令,所以 awk
仅接收一个文字符号作为输入,结果输出
<&>[&]
此字符串然后嵌入到 sed
的字符串中receives 作为它的参数,从中应该很明显为什么 sed
产生它所做的输出。
事件的顺序是
shell 看到这个命令行
sed -E 's/[^ ]*[A-Z][^ ]*.png/'$(echo \&|awk '{printf("<%s>[%s]",$0, tolower($0))}')'/' data
它处理命令替换(其中
awk
将&
变成<&>[&]
),以生成中间命令行sed -E 's/[^ ]*[A-Z][^ ]*.png/'<&>[&]'/' data
然后 shell 执行
sed
使用命令s/[^ ]*[A-Z][^ ]*.png/<&>[&]/
关于macos - 为什么这些简单的 shell 命令在 sed 的替换部分中使用时会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16673265/