gawk 用于使用变量将包含模式的行替换为多行

gawk use to replace a line containing a pattern with multiple lines using variable

我正在尝试用一组行替换包含使用 gawk 的模式的行。比方说,文件 aa 包含

aaaa
ccxyzcc
aaaa
ddxyzdd

我正在使用 gawk 将所有包含 xyz 的行替换为一组行 111\n222,我更改的内容将包含:

aaaa
111
222
aaaa
111
222

但是,如果我使用:

gawk -v nm2="111\n222" -v nm1="xyz" '{ if (/nm1/) print nm2;else print [=12=]}' "aa"

修改后的内容显示:

aaaa
ccxyzcc
aaaa
ddxyzdd

我需要包含 xyz 的整行,即 ccxyzccddxyzdd 行必须替换为 111,然后是 222。请帮忙。

您的代码的问题是 /nm1/ 试图匹配 nm1 作为模式而不是 nm1 变量

中的值
$ gawk -v nm2="111\n222" -v nm1="xyz" '[=10=] ~ nm1{print nm2; next} 1' aa
aaaa
111
222
aaaa
111
222

感谢@fedorqui 的建议,next 可以通过简单地覆盖与所需文本匹配的模式的输入行的内容来避免

gawk -v nm2="111\n222" -v nm1="xyz" '[=11=] ~ nm1{[=11=]=nm2} 1' aa


GNU 解决方案 sed

$ nm1='xyz'
$ nm2='111\n222'
$ sed "/$nm1/c $nm2" aa
aaaa
111
222
aaaa
111
222

c 命令将删除行匹配模式并添加给定的文本

当使用 awk's ~ 运算符时,您不需要在右侧提供文字正则表达式。

你的命令本身与不正确的语法更正是这样的,

gawk -v nm2="111\n222" -v nm1="xyz" '{ if ( [=10=] ~ nm1 ) print nm2;else print [=10=]}' input-file

产生输出。

aaaa
111
222
aaaa
111
222

我会这样做:

$ cat aa
aaaa
ccxyzcc
aaaa
ddxyzdd
$ awk '{gsub(/.*xyz.*/, "111\n222")}1' aa
aaaa
111
222
aaaa
111
222
$ 

将变量作为模式传递给 awk 总是有点棘手。

awk  -v nm2='111\n222'  '{if ( ~ /xyz/){ print nm2 } else {print}}'

将为您提供输出,但 'xyz' 模式现已修复。

将 nm1 作为 shell 变量传递也可以:

nm1=xyz
awk  -v nm2='111\n222'  '{if ( ~ /'$nm1'/){ print nm2 } else {print}}' aa