如何在 `sed` 中(例如,没有 PREFIXPREFIX)仅在路径前添加一次前缀(以幂等方式)?
How to prepend a PREFIX to paths only once (in an idempotent way) in `sed` (e.g., no PREFIXPREFIX)?
我有一个包含复杂多行命令和一些不相关文本的文件。我需要在某些路径(例如 /foo
)前加上前缀 /bar
。该脚本可以 运行 多次,但不得在同一路径前添加多个 /bar
前缀。例如,运行脚本一次得到/bar/foo
,运行再次得到,而仍然得到/bar/foo
,而不是[=16] =]. 为了与现有代码库保持一致,我必须使用 sed
。
我想出了想要的结果(如下),但我的方法似乎很麻烦。有没有更好的(更短、更少重复)的方式?
$ echo '/foo' > infile
$ cat infile
"/foo" /foo
# Replace once, change expected:
$ sed -i '\#bar/foo#!s#\(/foo\)#/bar#g' infile
$ cat infile
"/bar/foo" /bar/foo
# Replace twice - no change expected:
$ sed -i '\#bar/foo#!s#\(/foo\)#/bar#g' infile
$ cat infile
"/bar/foo" /bar/foo
编辑:不要使用我的“解决方案”:在重要的边缘情况下它是错误的,请参阅下面的评论
您可以将此 sed
解决方案与可选组一起使用,以将 /foo
替换为 /bar/foo
,但当 /bar
已经存在时跳过匹配:
sed -E 's~(/bar)?(/foo)~/bar~g' file
详情:
(/bar)?
:在捕获组 #1 中匹配 可选 /bar
(/foo)
:在捕获组 #2 中匹配 /foo
/bar
:替换为始终将 /bar
后跟我们在捕获组 #2 中捕获的值
我有一个包含复杂多行命令和一些不相关文本的文件。我需要在某些路径(例如 /foo
)前加上前缀 /bar
。该脚本可以 运行 多次,但不得在同一路径前添加多个 /bar
前缀。例如,运行脚本一次得到/bar/foo
,运行再次得到,而仍然得到/bar/foo
,而不是[=16] =]. 为了与现有代码库保持一致,我必须使用 sed
。
我想出了想要的结果(如下),但我的方法似乎很麻烦。有没有更好的(更短、更少重复)的方式?
$ echo '/foo' > infile
$ cat infile
"/foo" /foo
# Replace once, change expected:
$ sed -i '\#bar/foo#!s#\(/foo\)#/bar#g' infile
$ cat infile
"/bar/foo" /bar/foo
# Replace twice - no change expected:
$ sed -i '\#bar/foo#!s#\(/foo\)#/bar#g' infile
$ cat infile
"/bar/foo" /bar/foo
编辑:不要使用我的“解决方案”:在重要的边缘情况下它是错误的,请参阅下面的评论
您可以将此 sed
解决方案与可选组一起使用,以将 /foo
替换为 /bar/foo
,但当 /bar
已经存在时跳过匹配:
sed -E 's~(/bar)?(/foo)~/bar~g' file
详情:
(/bar)?
:在捕获组 #1 中匹配 可选 (/foo)
:在捕获组 #2 中匹配 /bar
:替换为始终将/bar
后跟我们在捕获组 #2 中捕获的值
/bar
/foo