选择行匹配模式,然后使用“sed”进行替换

选择行匹配模式,然后使用“sed”进行替换

这是我试图复制的内容:

$ cat << EOF | { var=$(grep 'foo=');\
 if (( $? == 0 )); then echo "$var"\
| sed -E 's/foo=(.+)/\1/'; else exit 1; fi; }
foo
foo=bar
EOF

酒吧

专门使用sed

$ cat << EOF | sed -nE '/foo=/p s/foo=(.+)/\1/'
foo
foo=bar
EOF

sed:-e表达式#1,字符9:命令后的额外字符

错误的原因是什么?如何修复它?

答案1

你正在尝试做

sed -n -E '/foo=/ s/foo=(.+)/\1/p' <<'END_INPUT'
foo
foo=bar
END_INPUT

您的命令p在初始地址(正则表达式foo=)之后有一个,这将其变成一个完整的sed编辑命令(带有抱怨的s/...as 尾随垃圾sed)而不是命令的地址s

在上面的命令中,/foo=/是后续命令的地址s。该s命令将应用于与正则表达式匹配的每一行foo=。该-n选项sed使其避免在每个循环后打印编辑缓冲区,这就是为什么我们p在命令中使用该标志s来打印修改后的行。

但是,您也可以将其写为

sed -n '/foo=./ s/foo=//p' <<'END_INPUT'
foo
foo=bar
END_INPUT

它删除foo=每行上有一个foo=位后跟一些内容的位。

或者,更短地说,通过让s命令重用用作地址的正则表达式(然后显然假设我们不要求)之后还有什么foo=

sed -n '/foo=/ s///p' <<'END_INPUT'
foo
foo=bar
END_INPUT

或者,更短地说,通过认识到该s命令无论如何都不会更改与正则表达式不匹配的行,

sed -n 's/foo=//p' <<'END_INPUT'
foo
foo=bar
END_INPUT

或者,在没有 的情况下-n,通过删除所有不感兴趣的行并仅修改感兴趣的行并依赖于循环结束时的默认输出,

sed -e '/foo=/!d' -e 's///' <<'END_INPUT'
foo
foo=bar
END_INPUT

相关内容