我找到了几种解决方法来删除两个字符串之间的文本,但我想我的情况有点不同。
我想转换这个:
/nz/kit.7.2.0.7/bin/adm/tools/hostaekresume
对此:
/nz/kit/bin/adm/tools/hostaekresume
基本上从文件名中删除特定于版本的信息。
我找到的解决方案会删除从kit
到/
的 last 出现的所有内容。我需要将某些内容从kit
移到第一个位置。
我见过的最常见的解决方案是:
sed -e 's/\(kit\).*\(\/\)/\1\2/'
产生:
/nz/kit/hostaekresume
如何才能删除第一个 /
?我认为这可以用sed或awk完成,但可以接受建议。
答案 0 :(得分:2)
$ sed 's|\(kit\)[^/]*|\1|' <<< '/nz/kit.7.2.0.7/bin/adm/tools/hostaekresume'
/nz/kit/bin/adm/tools/hostaekresume
这使用了不同的分隔符(|
而不是/
),因此我们不必逃避/
。然后,对于非贪婪匹配,它使用[^/]*
:除/
以外的任意数量的字符,它匹配kit
与下一个{{1}之间的所有内容}}
或者,如果您知道要删除的内容包含点和数字,并且字符串中没有其他内容包含它们,则可以使用parameter expansion:
/
语法为$ var='/nz/kit.7.2.0.7/bin/adm/tools/hostaekresume'
$ echo "${var//[[:digit:].]}"
/nz/kit/bin/adm/tools/hostaekresume
,其中展开的${parameter/pattern/string}
中的pattern
替换为parameter
。如果我们使用string
代替//
,则会替换所有匹配项而不是第一个匹配项。
在我们的例子中,/
是parameter
,模式是var
(数字或点 - 这是一个glob模式,顺便说一下,不是正则表达式),我们跳过了[[:digit:].]
部分,它只删除了模式(不用替换它)。
答案 1 :(得分:0)
非贪婪的正则表达式需要perl
。 sed
尚不这样做。
另外,使用|
作为分隔符,因为/
在你的正则表达式中有它时会引起混淆。
perl -pe 's|(kit).*?(/.*)|\1\2|'
?
之后的.*
使模式非贪婪,并且会匹配/
的第一个实例。
echo "/nz/kit.7.2.0.7/bin/adm/tools/hostaekresume" | perl -pe 's|(kit).*?(/.*)|\1\2|'
返回
/nz/kit/bin/adm/tools/hostaekresume
答案 2 :(得分:0)
echo "/nz/kit.7.2.0.7/bin/adm/tools/hostaekresume" | awk '{sub(/.7.2.0.7/,"")}1'
/nz/kit/bin/adm/tools/hostaekresume