解释awk命令

今天我正在寻找一个命令在网上打印下两行后,我遇到了一个awk命令,我无法理解。

$ /usr/xpg4/bin/awk '_&&_--;/PATTERN/{_=2}' input 

有人可以解释吗?

_在这里被用作variables名(有效但显然令人困惑)。 如果您将其重写为:

 awk 'x && x--; /PATTERN/ { x=2 }' input 

那么parsing起来会容易一点。 每当/PATTERN/匹配时,variables被设置为2 (并且该行不被输出) – 这是下半部分。 第一部分在x不为零时触发,并减lessx以及打印当前行(缺省操作,因为该子句不指定操作)。

最终的结果是在模式匹配后立即打印两行,只要这两行中的任何一行都不符合模式。

简单地说,在给定的正则expression式expression式匹配不包括匹配的行之后,该命令会打印多行。

行数在块{_=2}指定,如果行匹配PATTERN ,则variables_设置为2。 在匹配行之后读取的每一行都会导致_递减。 你可以阅读_&&_--就好像_大于零,然后减去1,匹配后的每一行都会发生这种情况,直到_命中零。 当你用一个更明智的名字如nreplacevariables_时,这很简单。

一个简单的演示应该清楚(打印任何符合foofoo的两行):

 $ cat file foo 1 2 3 foo a b c $ awk 'n && n--;/foo/{n=2}' file 1 2 a b 

所以当nfoo匹配后设为2时, n仅为真,然后递减n并打印当前行。 由于awk具有短路评估, n只在n为真(n> 0)时递减,所以在这种情况下对于n的唯一可能值是2,1或0。

Awk具有以下结构condition{block}并且当条件被评估为True时,对当前logging执行block。 如果你不提供一个块awk使用默认块{print $0}所以n && n--; 是在正则expression式匹配后没有块的情况下,只有n行的值为真。 分号只是为了条件n&&n--为条件/foo/划分条件/foo/明确规定条件没有阻塞。

要打印比赛之后的两条线,包括比赛,你应该这样做:

 $ awk '/foo/{n=3} n && n--' file foo 1 2 foo a b 

额外的:使用/usr/xpg4/bin/awk的完整path的事实告诉我这个代码是为Solaris机器devise的,因为/usr/bin/awk已经完全损坏了,应该不惜一切代价避免。

奇妙的隐晦。 时间允许时更新。

_正被用作variables名称。 &&是一个逻辑运算符,有两个真正的动作一起运行。 一旦_的值减到零,&&的后半部分就是假的,没有输出。

 print -- " xxxxx yyyy PATTERN zzz aa bbb ccc ddd" | awk '_&&_--;/PATTERN/{_=2}' 

产量

 zzz aa 

debugging版本

 print -- " xxxxx yyyy PATTERN zzz aa bbb ccc ddd" | awk '_&&_--;{print "_="_;print _&&_};/PATTERN/{_=2;print "_="_ }' 

产量

 _= 0 _= 0 _= 0 _= 0 _=2 zzz _=1 1 aa _=0 0 _=0 0 _=0 0 _=0 0 

说明

awkexpression式具有以下forms:

 condition action; NEXT_EXPRESSION 

如果条件是真的,则将执行动作。 进一步注意,如果条件为真,但操作被省略, awk将执行print (默认操作)。

你的代码中有两个expression式会在每行input中执行:

 _&&_-- ; /PATTERN/{_=2} 

两者相隔一个; 。 正如我所说的,如果省略了这个动作,就会发生默认的动作print ,就像下面这样

 _&&_-- {print}; /PATTERN/ {_=2} 

在你的例子中, _是一个variables名,它在第一行input前被0初始化,在awk中被自动初始化。

第一个条件是(0) && (0) ..什么结果是错误的,因为0 && 0评估为false ,awk不会打印。

如果find了模式, _将被设置为2 ,这使得第一个条件是(2) && (2)在下一行和(1) && (1)在该行之后的下一行,因为_在状况正在评估。 两者都评估为true ,awk将打印这些行。

然而,很好的谜题;)