我有以下变量,其中包含一个在目录树中显示文件夹的字符串:
root/f1/f2/f3/f4/f5
root/f1/f2/f3/f4
root/f1/f2/f3
我如何去除f2之前的所有内容,以便我留下的将是:
f2/f3/f4/f5
f2/f3/f4
f2/f3
答案 0 :(得分:2)
模糊的问题,模糊的回答
cut -f3- -d'/'
答案 1 :(得分:1)
sed
可能是最好的选择:
sed 's#.*/\(f2/\)#\1#' <<<"$var"
如果您可以假设GNU sed
或BSD / OSX sed
,则可以使用扩展正则表达式使命令更具可读性({{1} }):
-E
替代分隔符sed -E 's#.*/(f2/)#\1#' <<<"$var"
用于#
的{{1}}函数,以方便文字使用sed
字符。
s
匹配从行首到/
的所有内容,并捕获捕获组1中的.*/\(f2/\)
部分。
/f2/
子字符串,那么该行上 last 出现的f2/
的所有内容都将匹配。 然后将该行的匹配部分替换为/f2/
,即第一个(也是唯一的)捕获组捕获的字符串,根据需要有效地将整个匹配的字符串替换为/f2/
,然后是输入行的其余部分。
请注意,使用\1
通过stdin(所谓的here-string)提供变量值会假定f2/
,<<<
或bash
为外壳;
对于符合POSIX的解决方案,请使用ksh
如果要拆分的组件存储在变量中,请使用,例如:
zsh
请注意,这仅在printf '%s\n' "$var" | sed ...
不包含char时才有效。 name='f2'
sed 's#.*/\('"$name"'/\)#\1#' <<<"$var"
也不是任何正则表达元字符。
另请注意我是如何将 - 双引号 - shell 变量值中的拼接视为其他单 - 引用$name
脚本,以便清楚地说明shell对#
解释字符串的哪些部分。