次の入力ファイルinput.txt
スクリプトがあります
そして以下の出力を生成します。誰かがこのawk
スクリプトがどのように機能するかを分析するために時間を割いてください。私はそれに少し時間を費やしましたが、あまり意味がありません。
入力:
$ cat input.txt
FINISHED RSYNCJOBNA 20140502 0021 2182096 2082096 6 5 2014820905820902 10:02:15 2014820905820902 10:56:42 0:54:27 INITIATED RSYNCJOBNA 20140502 0022 3282096 3182096 6 5 2014820905820902 15:31:06 0:06:04 ce eque**
出力:
RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED
上記の出力を取得するコマンド:
awk -v OFS="|" "/FINISHED|INITIATED/ { status = $1; getline; jobname = $1; getline; sequence = $2; date = $1; getline; start = $2; getline; if (status == "FINISHED") { end = $2; getline } else { end = " " } runtime = $1; print jobname, sequence, date, start, end, runtime, status; }" input.txt
私の理解では/FINISHED|INITIATED/ {}
は、中括弧内のコマンドがFINISHED
またはINITIATED
のいずれかに一致する行でのみ実行されることを意味します。出力からわかる限り、スクリプトはすべての行から解析しているようです。何が起こっているのですか?
コメント
回答
getline
関数は次の行を読み取り、スクリプトをその行に移動します。連続するgetline
呼び出しは次の行に移動します。これは、例を使用するとおそらく理解しやすくなります。
$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2
As上記のように、スクリプトはfoo
と一致するため、最初の行を処理します。 getline
を呼び出すたびに、現在の行の次の行が読み取られるため、後続のprint
呼び出しは次の行を出力します。
回答
awk
関数の機能がわからない場合、通常の戦略は次のとおりです。マニュアルページを見るには:
getline
次の入力レコードから$ 0を設定し、NF、NR、FNR、 RT
コマンドブロックは実際には2回だけ実行されます。他の行は、getline
を介して内部から処理されます。ブロック。
これは次のように書き換えることができます:
/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ...
コメント
- 次のレコードが空のレコードである場合はどうなりますか?
- @AvinashRajコードも私の代替も行の内容を調べません(
/FINISHED|INITIATED/
を除く) )行はカウントダウンされます。データは正確に配置する必要があります(awk parsiから) ngパースペクティブ)あなたが示した方法で、そうでなければコードは壊れます。
/FINISHED|INITIATED/
のようなパターンを指定すると、awkは対応する行を検索し、その特定の行でのみ操作を実行します。しかし、操作はすべての行で実行されました。どのように?