sed匹配模式的第二次出现

时间:2017-01-03 05:54:15

标签: bash unix awk sed

更新问题:

我有一个文件包含下面提到的两种格式之一的代码块:

1

    $Subj .= "HAD PROBLEMS";

    if ($To) {
        $Cc = "abc\@example.com";
    }
    else {
        $Cc = "abc\@example.com";
    }

2

    $Subj .= "HAD PROBLEMS";

    if ($To) { $Cc = "abc\@example.com"; } else { $Cc = "abc\@example.com"; }

我需要将$ Cc变量(第2次出现)中的电子邮件ID替换为两种格式的新电子邮件ID。

我有以下sed命令来执行此操作。

sed '\|HAD PROBLEMS|,/}/ s/$Cc = \(\"[A-Za-z0-9]*\)\(.*\)\([A-Za-z0-9]*\)\@example.com\"/\$Cc = "new email\\@example.com"/' test.txt

此命令将仅替换if $Cc块中的{}变量的电子邮件ID(第一次出现$Cc),因为我的结束匹配模式为'}'。我想在第二个$Cc中替换电子邮件ID。我如何匹配'}'的第二次出现?

下面提到的解决方案适用于第一种格式。但我需要一个适用于这两种格式的通用解决方案。任何人都可以帮忙。

我希望描述清楚。

1 个答案:

答案 0 :(得分:0)

在我看来,awk是一种更清晰的语言来表达这个问题。

awk '/HAD PROBLEMS/{x=1} /}/{x++} x==2&&/\$Cc =/{sub(/[a-z]+\\@[a-z.-]+/,"new@example.com"); unset x} 1' input.txt

或者间隔开以便于评论:

# search for your start pattern, set a counter.
/HAD PROBLEMS/ {x=1}        

# increment the counter at the first close-squigly.
/}/ {x++}                   

# If we've done our increment and we're on the right line,
x==2 && /\$Cc =/ {          
  # substitute the existing address with a new one,
  sub(/[a-z]+\\@[a-z.-]+/,"new@example.com");
  # and reset our counter.
  unset x
}

# Print the current line.
1