删除一个字符串与第一次出现另一个字符串之间的文本

时间:2016-06-17 20:07:04

标签: linux awk sed

我找到了几种解决方法来删除两个字符串之间的文本,但我想我的情况有点不同。

我想转换这个:

/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完成,但可以接受建议。

3 个答案:

答案 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)

非贪婪的正则表达式需要perlsed尚不这样做。 另外,使用|作为分隔符,因为/在你的正则表达式中有它时会引起混淆。

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