在AWK中,跳过当前操作的其余部分吗?

时间:2019-01-25 00:47:34

标签: awk

感谢您的光临。

我有一个类似AWK的脚本;

/^test/{
  if ($2 == "2") {
    # What goes here?
  }

  # Do some more stuff with lines that match test, but $2 != "2".
}


NR>1 {
  print $0
}

我想跳过其余的动作,但是在同一行上处理其余的模式/动作。

我已经尝试过return,但这不是一个功能。 我已经尝试过next,但这会跳过当前行的其余模式/操作。

到目前为止,我已经将^test动作的其余部分包装在if语句的else中,但是我想知道是否有更好的方法。

不确定这是否重要,但我正在OSX上使用gawk安装的brew(为了更好地与目标OS兼容)。

更新(含解决方案):

编辑:根据@karakfa的答案扩展了代码示例。

BEGIN{
  keepLastLine = 1;
}
/^test/ && !keepLastLine{
  printLine = 1;
  print $0;
  next;
}

/^test/ && keepLastLine{
  printLine = 0;
  next;
}

/^foo/{
  # This is where I have the rest of my logic (approx 100 lines), 
  # including updates to printLine and keepLastLine
}

NR>1 {
  if (printLine) {
    print $0
  }
}

这将对我有用,我什至更喜欢我所想的。

但是我确实想知道我的keepLastLine条件只能在for循环中访问吗?

我从@karakfa所说的中得知,没有一个仅用于退出动作并继续其他模式的控制结构,因此必须使用某种标志来实现(与@ RavinderSingh13的答案不同) )。

2 个答案:

答案 0 :(得分:2)

如果我正确无误,请尝试以下操作。我在此处创建一个名为flag的变量,如果检查第二字段是否为2的test块内的条件为TRUE,则将设置该变量为SET。设置为SET时,将不会执行test BLOCK中的其余语句。还要在开始读取行之前重置标志的值。

awk '
{
 found=""
}
/^test/{
  if ($2 == "2") {
    # What goes here?
    found=1
  }
  if(!found){
  # Do some more stuff with lines that match test, but $2 != "2".
  }
}
NR>1 {
  print $0
}'  Input_file


此处的代码测试:

让我们说以下是Input_file:

cat Input_file
file
test 2 file
test
abcd

在运行以下代码之后,我们将获得以下输出,如果任何行具有test关键字而没有$2==2,那么它将执行test条件之外的语句。

awk '
{
 found=""
}
/^test/{
  if ($2 == "2") {
    print "# What goes here?"
    found=1
  }
  if(!found){
   print "Do some more stuff with lines that match test, but $2 != 2"
  }
}
NR>1 {
  print $0
}'   Input_file
# What goes here?
test 2 file
Do some more stuff with lines that match test, but $2 != 2
test
abcd

答案 1 :(得分:1)

您要寻找的魔术关键字是else

/^test/{ if($2==2) {  } # do something
         else {  }      # do something else  
       }

NR>1                    # {print $0} is implied. 

由于某些原因,如果您不想使用else,只需将条件向上移动一个(拉平层次结构)

/^test/ && $2==2 {  } # do something
/^test/ && $2!=2 {  } # do something else  
# other action{statement}s