2013-08-23 5 views
16

今日私はパターンの次の2行を印刷するためにオンラインでコマンドを検索していました。私は理解できないawkコマンドを見つけました。awkコマンドを説明してください

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

誰か説明できますか?

答えて

2

すばらしくわかりません。時間が許せば更新されます。

_が変数名として使用されています。 &&は、2つの真のアクションが一緒に実行される論理演算子です。 _の値が0に減少すると、& &の後半は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 
7

単純に、指定された正規表現式が一致する行を除いて一致した後に、コマンドはいくつかの行を出力します。

行番号がブロック{_=2}に指定され、行がPATTERNに一致する場合は、変数_が2に設定されます。一致する行の後に読み込まれるすべての行は、_をデクリメントします。 _がゼロより大きく、それからマイナス1のように_&&_--を読み取ることができます。これは、一致後にすべての行で、_がゼロになるまで発生します。変数_nのようなより賢明な名前に置き換えると非常に簡単です。

簡単なデモは、それが明確な(fooに一致する任意の行に続く2行を出力)にする必要があります。

$ cat file 
foo 
1 
2 
3 
foo 
a 
b 
c 

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

それはそれをfooでラインをマッチングした後、2に設定されますときにnにのみ真でありますnをデクリメントし、現在の行を出力します。 nがTrue (N> 0)のでnため、この場合の唯一の可能な値は、2,1または0

awkは、以下の構造を有しているcondition{block}及び場合によりawkが短絡評価nを有するだけデクリメントされます条件がTrueと評価されると、現在のレコードに対してブロックが実行されます。ブロックを指定しない場合awkはデフォルトブロック{print $0}を使用します。したがって、n && n--;は、正規表現の一致後にn行のTrueと評価されるブロックのない条件です。セミコロンは条件/foo/に対して条件n&&n--を区切り、条件にブロックがないことを明示します。余分なエキストラ

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

/usr/xpg4/bin/awkの完全なパスが使用されているという事実は、このコードは、Solarisのために意図されて私に指示、あなたがどうなるの一致を含む一致次の2行を印刷するには

マシンは/usr/bin/awkとして完全に壊れており、絶対に避けてください。

+2

非常に良い説明 – CBR

11

_がここでは変数名として使用されています(ただし、明らかに混乱します)。

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

次のように書き直すと、少し解析しやすくなります。 /PATTERN/が一致するたびに、変数は2に設定され(その行は出力されません)、それは後半です。最初の部分は、xがゼロでないときに起動し、xをデクリメントするとともに、現在の行を印刷します(デフォルトのアクション、その句はアクションを指定しないため)。

最終的には、どちらのパターンもパターンに一致しない限り、パターンの一致の直後に2行を印刷することになります。 conditonが真のアクション(複数可)が実行される場合には

condition action; NEXT_EXPRESSION 

2

説明

awk式は次の形式を持っています。さらに、条件が真であるがアクションが省略された場合、awkprint(デフォルトアクション)を実行します。

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

両方が;で区切られています。

あなたが入力のすべての行で実行されます、あなたのコード内の2つの式を持っています。私はアクションはそれが省略された場合のデフォルト動作printが起こるだろうと言われましたよう同じとして:あなたの例では

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

_は、入力の最初の行に0で初期化される変数名、です、それが最初の使用の前に - awkによって自動的に。

最初の条件は(0) && (0)となります。0 && 0falseと評価され、awkは印刷されないため、結果はfalseになります。

パターンが見つかった場合、_条件が評価された後_としてその行がデクリメントされた後、次の行の次の行に(2) && (2)(1) && (1)である第1の条件になるた2に設定されます。両方ともtrueと評価されており、awkはこれらの行を出力します。しかし、素敵なパズル

;)

+0

ポストデクリメントは、論理ANDで明示的に '(0)&&(0 - )'( '0 && 0) - 'が-1と評価されるより高い順番または優先順位を持ちます。 –

+0

知っておいしい..私はそのように投稿を強化させてください。 – hek2mgl

+0

@sudo_O 'awk '_ &&_--; 1 {printf"%i \ n "、_};/Pattern/{_ = 2}' input.txt'私は上記の行の出力を理解していません。パターンが一致した後、減算が(awkドキュメントに適合していれば、あなたは正しい)、最初のテストでは '&&'の右側が1になり、2番目のテストでは0になります。だから私はただ一つの行が印刷されることを期待するだろう..私はここで何が欠けていますか? – hek2mgl

関連する問題