コマンドの出力を正規表現使って文字列置換するならsed
を使うことは多いけど、行ごとに処理するだけで「前の行の情報」などどうだったかとかの状態を維持する仕組みが(たぶん)ないので、例えば「特定の文字列パターンを正規表現で処理しつつ連番を振る」がsed
は(たぶん)できない。(連番の部分)
この要件ならawk
を使えばできる。
お題:ps aux
の結果の行頭に行番号を3桁ゼロ詰めで追加
お題そのものは全く実用的ではないけど、変数使った正規表現置換という例。
コマンドは以下。
ps aux | awk '{sub(/^/, sprintf("%03d: ", ++i)); print}'
AWKはsub(regexp, replace)
で正規表現置換するので、/^/
で行頭をsprintf("%03d: ", ++i)
で3桁ゼロ埋めの連番に置換し、最後にprint
する、という寸法。
出力は以下の通り。
$ ps aux | awk '{sub(/^/, sprintf("%03d: ", ++i)); print}' 001: USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 002: root 1 0.0 0.1 47584 14500 ? Ss 5月07 0:16 /usr/lib/systemd/systemd --system --deserialize=167 rhgb 003: root 2 0.0 0.0 0 0 ? S 5月07 0:00 [kthreadd] 004: root 3 0.0 0.0 0 0 ? S 5月07 0:00 [pool_workqueue_release] 005: root 4 0.0 0.0 0 0 ? I< 5月07 0:00 [kworker/R-kvfree_rcu_reclaim] [snip]
Perlの場合
最初はsed
でできるかと思ってコマンドライン書き始めたらうまくいかなかったのでawk
を試したが、少し込み入った正規表現置換するならperl
の方がすっきり書けるかも。
同じお題を処理するなら以下。
ps aux | perl -pe 's/^/sprintf("%03d: ", ++$i)/e'
-p
を付けるとprint
が不要になるので少し短く書ける。
補足