【问题标题】:How to replace a few matches in one line using sed如何使用 sed 替换一行中的几个匹配项
【发布时间】:2011-03-22 01:10:32
【问题描述】:

如何使用 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 文件="文件.log" OLD="somepath1\/somepath_.*\/somepath3" NEW="mysomepath1\/mysomepath2\/mysomepath3" sed 's|'"$OLD"'|'"$NEW"'|g' $FILE > $FILE.out

表达有什么问题?

【问题讨论】:

  • 那是因为你 sed 正则表达式是贪婪的。

标签: bash sed


【解决方案1】:

尝试使用 [^/] 代替 .

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

否则,将 sed 替换为支持类 sed 调用的 perl:

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

在哪里。?与 . 相同,但它不是贪婪的。

【讨论】:

  • 谢谢马尔科!替换 [^/] 而不是 .完美运行。现在我有了预期的输出。
【解决方案2】:
#!/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;

【讨论】:

  • 谢谢ghostdog74。它运作良好。但我需要将 sed 用于当前任务。
猜你喜欢
  • 2018-04-08
  • 1970-01-01
  • 2018-12-18
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
相关资源
最近更新 更多