今日私はパターンの次の2行を印刷するためにオンラインでコマンドを検索していました。私は理解できないawkコマンドを見つけました。awkコマンドを説明してください
$ /usr/xpg4/bin/awk '_&&_--;/PATTERN/{_=2}' input
誰か説明できますか?
今日私はパターンの次の2行を印刷するためにオンラインでコマンドを検索していました。私は理解できないawkコマンドを見つけました。awkコマンドを説明してください
$ /usr/xpg4/bin/awk '_&&_--;/PATTERN/{_=2}' input
誰か説明できますか?
すばらしくわかりません。時間が許せば更新されます。
_
が変数名として使用されています。 &&
は、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
単純に、指定された正規表現式が一致する行を除いて一致した後に、コマンドはいくつかの行を出力します。
行番号がブロック{_=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
として完全に壊れており、絶対に避けてください。
_
がここでは変数名として使用されています(ただし、明らかに混乱します)。
awk 'x && x--; /PATTERN/ { x=2 }' input
次のように書き直すと、少し解析しやすくなります。 /PATTERN/
が一致するたびに、変数は2
に設定され(その行は出力されません)、それは後半です。最初の部分は、x
がゼロでないときに起動し、x
をデクリメントするとともに、現在の行を印刷します(デフォルトのアクション、その句はアクションを指定しないため)。
最終的には、どちらのパターンもパターンに一致しない限り、パターンの一致の直後に2行を印刷することになります。 conditonが真のアクション(複数可)が実行される場合には
condition action; NEXT_EXPRESSION
:
説明
awk
式は次の形式を持っています。さらに、条件が真であるがアクションが省略された場合、awk
はprint
(デフォルトアクション)を実行します。
_&&_-- ;
/PATTERN/{_=2}
両方が;
で区切られています。
あなたが入力のすべての行で実行されます、あなたのコード内の2つの式を持っています。私はアクションはそれが省略された場合のデフォルト動作print
が起こるだろうと言われましたよう同じとして:あなたの例では
_&&_-- {print};
/PATTERN/ {_=2}
_
は、入力の最初の行に0
で初期化される変数名、です、それが最初の使用の前に - awkによって自動的に。
最初の条件は(0) && (0)
となります。0 && 0
はfalse
と評価され、awkは印刷されないため、結果はfalseになります。
パターンが見つかった場合、_
条件が評価された後_
としてその行がデクリメントされた後、次の行の次の行に(2) && (2)
と(1) && (1)
である第1の条件になるた2
に設定されます。両方ともtrue
と評価されており、awkはこれらの行を出力します。しかし、素敵なパズル
;)
ポストデクリメントは、論理ANDで明示的に '(0)&&(0 - )'( '0 && 0) - 'が-1と評価されるより高い順番または優先順位を持ちます。 –
知っておいしい..私はそのように投稿を強化させてください。 – hek2mgl
@sudo_O 'awk '_ &&_--; 1 {printf"%i \ n "、_};/Pattern/{_ = 2}' input.txt'私は上記の行の出力を理解していません。パターンが一致した後、減算が(awkドキュメントに適合していれば、あなたは正しい)、最初のテストでは '&&'の右側が1になり、2番目のテストでは0になります。だから私はただ一つの行が印刷されることを期待するだろう..私はここで何が欠けていますか? – hek2mgl
は、ここでは重複した回答をhttps://stackoverflow.com/a/17914105/1745001参照してください。
非常に良い説明 – CBR