解释awk命令

时间:2013-08-23 16:43:40

标签: unix awk

今天我在网上搜索一个命令,在模式后打印下两行,我遇到了一个我无法理解的awk命令。

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

有人可以解释一下吗?

5 个答案:

答案 0 :(得分:37)

有关此处重复的答案,请参阅https://stackoverflow.com/a/17914105/1745001

答案 1 :(得分:13)

_在这里被用作变量名称(有效但显然令人困惑)。如果你把它重写为:

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

那么解析会更容易一些。每当/PATTERN/匹配时,变量将设置为2(并且不输出该行) - 这是下半部分。第一部分在x不为零时触发,并递减x以及打印当前行(默认操作,因为该子句未指定操作)。

最终结果是在模式匹配后立即打印两条线,只要这些线都不匹配模式。

答案 2 :(得分:8)

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

行数{_=2}中指定行数,如果行匹配_,则变量PATTERN设置为2。匹配行后读取的每一行都会导致_递减。你可以阅读_&&_--,好像_大于零,然后减去它,这在匹配后的每一行都会发生,直到_达到零。使用更合理的名称_替换变量n时,这非常简单。

一个简单的演示应该清楚(打印跟随foo的任何一行的2行:

$ cat file
foo
1
2
3
foo
a
b
c

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

所以n仅在将一行与foo匹配后设置为2时才为True,然后递减n并打印当前行。由于awk短路评估n仅在n为真(n> 0)时递减,所以在这种情况下n唯一可能的值condition{block} 1}}是2,1或0.

Awk具有以下结构awk,当条件被评估为True时,则对当前记录执行block。如果您未提供块{print $0},则使用默认块n && n--;,因此n是一个没有块的条件,只有在正则表达式后n&&n--行的计算结果为True比赛。分号只是为条件/foo/界定条件$ awk '/foo/{n=3} n && n--' file foo 1 2 foo a b ,使条件明确表示条件没有阻塞。

要打印匹配后的两行,包括您将要执行的匹配:

/usr/xpg4/bin/awk

额外额外:使用/usr/bin/awk的完整路径这一事实告诉我这个代码是针对Solaris机器的,因为{{1}}完全被破坏了,应该是不惜一切代价避免。

答案 3 :(得分:3)

<强>解释

awk表达式具有以下形式:

condition action; NEXT_EXPRESSION

如果条件为真,则将执行操作。进一步说明,如果condition为true但是省略了action awk将执行print(默认操作)。

您的代码中有两个表达式将在每一行输入上执行:

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

两者都以;分隔。正如我所说,如果省略该操作,将发生默认操作print相同:

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

在您的示例中,_是一个变量名称,在第一次使用之前由0初始化,在第一次使用之前 - 由awk自动生成。

第一个条件是(0) && (0) ..导致条件为假的原因是,0 && 0评估为false而awk不会打印。

如果找到模式,_将设置为2,这使得下一行的第一个条件为(2) && (2),之后的下一行为(1) && (1)作为_的行在评估条件后递减。两者都在评估true,而awk将打印这些行。

然而,很好的谜题;)

答案 4 :(得分:2)

奇妙的模糊。将在时间允许时更新。

_被用作变量名。 &&是一个逻辑运算符,它有2个真正的动作一起运行。一旦_的值减小到零,&amp;&amp;的下半部分。为false,不生成输出。

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

<强>输出

zzz
aa

调试版

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