以下命令可以正确使用 UID 和 GID 替换文本用户名和组名:
echo "uidNumber=root" | sed -E 's/((u|g)idNumber=)([^,+]+)/echo -n \1; id -\2 \3/eg'
uidNumber=0
但是,如果在模式匹配的文本之前添加文本,则会将其添加到替换中执行的命令之前并导致失败:
echo "anotherAttr,uidNumber=root" | sed -E 's/((u|g)idNumber=)([^,+]+)/echo -n \1; id -\2 \3/eg'
h: line 1: anotherAttr,echo: command not found
0
如果在模式匹配的文本之后添加文本,似乎也会发生同样的情况,在这种情况下,它会被附加:
echo "anotherAttr1,uidNumber=root,anotherAttr2" | sed -E 's/((u|g)idNumber=)([^,+]+)/echo -n \1; id -\2 \3/eg'
sh: line 1: anotherAttr1,echo: command not found
id: ‘root,anotherAttr2’: no such user
为什么在执行的命令中附加和前置不匹配的文本,如何阻止这种情况发生?
编辑:其他用户建议匹配整行,但这会阻止g
修改器正常运行,并且不是可接受的解决方案。
答案1
这个问题是由于对修改器工作原理的根本误解造成的e
。
替换s
可以应用一次,也可以应用到整个模式缓冲区(在 的情况下g
)。e
然后在执行替换后执行模式缓冲区的内容。
修复方法非常简单,转义美元和斜杠,添加echo -n "
到模式缓冲区,追加"
到模式缓冲区,并将所有每个替换命令放入子 shell 扩展中。
添加p
通过向我们展示将执行的内容来帮助调试:
echo "anotherAttr1,uidNumber=root,gidNumber=root,anotherAttr2" | sed -E 's/\\/\\\\/g;s/\$/\\$/g;s/^/echo "/;s/$/"/;s/((u|g)idNumber=)([^,+]+)/\1$(id -\2 \3)/peg'
echo "anotherAttr1,uidNumber=$(id -u root),gidNumber=$(id -g root),anotherAttr2"
anotherAttr1,uidNumber=0,gidNumber=0,anotherAttr2