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

时间:2016-10-05 10:54:41

标签: bash awk gawk

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

aaaa
ccxyzcc
aaaa
ddxyzdd

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

aaaa
111
222
aaaa
111
222

但是,如果我使用:

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

更改的内容显示:

aaaa
ccxyzcc
aaaa
ddxyzdd

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

4 个答案:

答案 0 :(得分:3)

您的代码存在的问题是,/nm1/尝试将nm1作为模式匹配,而不是nm1变量中的值

$ gawk -v nm2="111\n222" -v nm1="xyz" '$0 ~ nm1{print nm2; next} 1' aa
aaaa
111
222
aaaa
111
222

感谢@fedorqui的建议,只需覆盖与所需文本匹配的模式的输入行内容即可避免next

gawk -v nm2="111\n222" -v nm1="xyz" '$0 ~ nm1{$0=nm2} 1' aa


使用GNU sed

的解决方案
$ nm1='xyz'
$ nm2='111\n222'
$ sed "/$nm1/c $nm2" aa
aaaa
111
222
aaaa
111
222

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

答案 1 :(得分:1)

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

你的命令就像修正不正确的语法一样,

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

产生输出。

aaaa
111
222
aaaa
111
222

答案 2 :(得分:1)

我就是这样做的:

if (first.contains("a") || first.contains("A")) {
  System.out.print("How many to remove from pile " + first + "? ");
  int second = input.nextInt();
  input.nextLine(); // firing an blank nextLine call
  count = count + 1;
  a = a - second;
  System.out.println("A: " + a + " B: " + b + " C: " + c);

  if(a <= 0 && b <= 0 && c <= 0){
     break nim_loop;
  }

答案 3 :(得分:0)

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

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

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

将nm1作为shell变量传递也将起作用:

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