使用sed替换2行模式中的单词

时间:2014-05-31 00:42:39

标签: perl sed substitution

我尝试使用sed将2行模式中的单词替换为另一个单词。当在一行中时,模式' MACRO""''然后在下一行找到替换' BLOCK'与核心'。 "东西"将被引入参考并打印出来。

我的输入数据:

MACRO ABCD
  CLASS BLOCK ;
  SYMMETRY X Y ;

期望的结果:

MACRO ABCD
  CLASS CORE ;
  SYMMETRY X Y ;

到目前为止我在sed的尝试:

sed 's/MACRO \([A-Za-z0-9]*\)/,/  CLASS BLOCK ;/MACRO \1\n  CLASS CORE ;/g' input.txt

上述内容无法发出消息:

sed: -e expression #1, char 30: unknown option to `s'

我错过了什么?

我也可以在perl中使用单线解决方案。

谢谢, 格特

5 个答案:

答案 0 :(得分:3)

在slurp模式下使用perl one-liner:

perl -0777 -pe 's/MACRO \w+\n  CLASS \KBLOCK ;/CORE ;/g' input.txt

或使用流媒体示例:

perl -pe '
    s/^\s*\bCLASS \KBLOCK ;/CORE ;/ if $prev;
    $prev = $_ =~ /^MACRO \w+$/
  ' input.txt

说明:

切换

  • -0777:Slurp文件整个
  • -p:为输入文件中的每一行创建一个while(<>){...; print}循环。
  • -e:告诉perl在命令行上执行代码。

答案 1 :(得分:3)

  

当在一行中时,“MACRO”模式会在“   下一行用'CORE'替换'BLOCK'。

sed适用于输入的。如果要在指定模式的下一行上执行替换,则需要将其添加到模式空间,然后才能执行此操作。

以下内容可能适合您:

sed '/MACRO/{N;s/\(CLASS \)BLOCK/\1CORE/;}' filename

从文档中引用:

  

`N'

 Add a newline to the pattern space, then append the next line of
 input to the pattern space.  If there is no more input then sed
 exits without processing any more commands.

如果您想在尝试时使用地址范围,则需要:

 sed '/MACRO/,/CLASS BLOCK/{s/\(CLASS\) BLOCK/\1 CORE/}' filename

我不确定为什么你需要一个反向引用代替宏名。

答案 2 :(得分:0)

这可以做到

#!awk -f
BEGIN {
  RS = ";"
}
/MACRO/ {
  sub("BLOCK", "CORE")
}
{
  printf s++ ? ";" $0 : $0
}
  • “line”以;
  • 结尾 在BLOCK 的“行”中为CORE
  • MACRO
  • 打印;后跟“line”,除非第一行

答案 3 :(得分:0)

你也可以尝试这个awk命令,

awk '{print}/MACRO/ {getline; sub (/BLOCK/,"CORE");{print}}' file

它按原样打印所有行,并在一行上看到一个单词MACRO时执行替换操作。

答案 4 :(得分:0)

由于getline有很多陷阱,我尽量不使用它,所以:

awk '/MACRO/ {a++} a==1 {sub(/BLOCK/,"CORE")}1' file
MACRO ABCD
  CLASS CORE ;
  SYMMETRY X Y ;