Regex 如何使用sed替换字符串的一部分

Regex 如何使用sed替换字符串的一部分,regex,sed,Regex,Sed,我想得到一些帮助,用XXX替换标签和核心之间的内容。所以我想要的输出是/home/repository/tags/XXX/core 字符串是一个目录路径,其中/home/repository/tags是唯一不变的部分。这条路总是有六层深。所以它可能并不总是在标签和核心之间 echo "/home/repository/tags/1.9.1/1.9.1.8/core" | sed "s/HELP/XXX/g" 产量 echo "/home/repository/whatever/1.9.1/1.

我想得到一些帮助,用XXX替换标签和核心之间的内容。所以我想要的输出是/home/repository/tags/XXX/core

字符串是一个目录路径,其中/home/repository/tags是唯一不变的部分。这条路总是有六层深。所以它可能并不总是在标签和核心之间

echo "/home/repository/tags/1.9.1/1.9.1.8/core" | sed "s/HELP/XXX/g"
产量

echo "/home/repository/whatever/1.9.1/1.9.1.8/core/and/more/junk"   \
| sed 's@\(/[^/]*/[^/]*/[^/]*\)/[^/]*/[^/]*@\1/XXX@'

如果目录始终为6层深,则此操作有效(请记住转义圆括号):

产生:

echo "/home/repository/tags/1.9.1/1.9.1.8/core" | 
sed 's/\(\/home\/repository\/tags\/\).*\/.*\(\/.*\)/\1XXX\2/'

在这里,你可以省去一些正则表达式的痛苦:

/home/repository/tags/XXX/core

如果您真正想做的只是去掉
标记/
和最后一个组件之间的所有内容,那么无需显式匹配组件。请注意,我使用的是
+
而不是
*
,因此该组件必须是非空的。这将防止出现尾随斜杠。

通过使用重复量词,您可以轻松调整替换位置:

echo "/home/repository/tags/1.9.1/1.9.1.8/core" | sed 's@/home/repository/tags/.*/\(.\+\)$@/home/repository/tags/XXX/\1@'
  • 3表示开始时要保留的组件数
  • 2表示要替换的数量
您甚至可以使用变量:

echo "/home/repository/tags/1.9.1/1.9.1.8/core" | \
    sed -r 's|(/([^/]+/){3})([^/]+/){2}(.*)|\1XXX/\4|'

澄清一下:你想总是用一个特定的字符串替换路径的第四和第五个组件吗?是的,我可以说可能有六个以上的组件。我喜欢@as分隔符。我总是忘记你能做到。您的解决方案更加健壮。
echo "/home/repository/tags/1.9.1/1.9.1.8/core" | \
    sed -r 's|(/([^/]+/){3})([^/]+/){2}(.*)|\1XXX/\4|'
$ dirs='/one/two/three/four/five/six/seven/eight'
$ for keep in {0..3}; do for replace in {0..3}; do echo "$dirs" | \
    sed -r "s|(/([^/]+/){$keep})([^/]+/){$replace}(.*)|\1XXX/\4|"; done; done
/XXX/one/two/three/four/five/six/seven/eight
/XXX/two/three/four/five/six/seven/eight
/XXX/three/four/five/six/seven/eight
/XXX/four/five/six/seven/eight
/one/XXX/two/three/four/five/six/seven/eight
/one/XXX/three/four/five/six/seven/eight
/one/XXX/four/five/six/seven/eight
/one/XXX/five/six/seven/eight
/one/two/XXX/three/four/five/six/seven/eight
/one/two/XXX/four/five/six/seven/eight
/one/two/XXX/five/six/seven/eight
/one/two/XXX/six/seven/eight
/one/two/three/XXX/four/five/six/seven/eight
/one/two/three/XXX/five/six/seven/eight
/one/two/three/XXX/six/seven/eight
/one/two/three/XXX/seven/eight