如何使用sed替换一行中的几个匹配项

时间:2010-07-28 09:01:56

标签: bash sed

如何使用sed替换一行中的几个匹配项?

我有一个带文字的file.log:

sometext1;/somepath1/somepath_abc123/somepath3/file1.a;/somepath1/somepath_abc123/somepath3/file1.o;/somepath1/somepath_abc123/somepath3/file1.cpp;
sometext2;/somepath1/somepath_abc123/somepath3/file2.a;/somepath/somepath_abc123/somepath3/file2.o;/somepath1/somepath_abc123/somepath3/file2.cpp;

我正在尝试替换每行中的somepath1/somepath_abc123/somepath3

但结果不太可能出错:

sometext1;/mysomepath1/mysomepath2/mysomepath3/file1.cpp;
sometext2;/mysomepath1/mysomepath2/mysomepath3/file2.cpp;

正如您所见,sed仅返回最后一场比赛。

我尝试了以下代码:

#!/bin/sh
FILE="file.log"
OLD="somepath1\/somepath_.*\/somepath3"
NEW="mysomepath1\/mysomepath2\/mysomepath3"
sed  's|'"$OLD"'|'"$NEW"'|g' $FILE > $FILE.out

表达方式有什么问题?

2 个答案:

答案 0 :(得分:3)

尝试使用[^ /]代替。

#!/bin/sh
FILE="file.log"
OLD="somepath1/somepath_[^/]*/somepath3"
NEW="mysomepath1/mysomepath2/mysomepath3"
sed  "s|$OLD|$NEW|g" $FILE > $FILE.out

否则,用perl替换sed,它支持类似sed的调用:

#!/bin/sh
FILE="file.log"
OLD="somepath1/somepath_.*?/somepath3"
NEW="mysomepath1/mysomepath2/mysomepath3"
perl -pe "s|$OLD|$NEW|g" $FILE > $FILE.out

在哪里。?与。相同,但它不贪心。

答案 1 :(得分:1)

#!/bin/bash

awk -F";" '
{
  for(i=1;i<=NF;i++){
    if($i ~ /somepath1.*somepath3/ ){
      sub(/somepath1\/somepath_.*\/somepath3/,"mysomepath1/mysomepath2/mysomepath3",$i)
    }
  }
}
1' OFS=";" file

输出

$ ./shell.sh
sometext1;/mysomepath1/mysomepath2/mysomepath3/file1.a;/mysomepath1/mysomepath2/mysomepath3/file1.o;/mysomepath1/mysomepath2/mysomepath3/file1.cpp;
sometext2;/mysomepath1/mysomepath2/mysomepath3/file2.a;/somepath/somepath_abc123/somepath3/file2.o;/mysomepath1/mysomepath2/mysomepath3/file2.cpp;