我尝试使用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中使用单线解决方案。
谢谢, 格特
答案 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
}
;
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 ;