何らかの入力がある場合、アクションを実行する前にデータをフィルタリングしたほうがよいでしょうかawk
、それとも ですべてのフィルタリングを実行する必要がありますかawk
?
たとえば、次の入力があるとします。
$ echo "foo\nbar\nbaz"
foo
bar
baz
実行する必要がありますか:
$ echo "foo\nbar\nbaz" | sed 1q | awk '{ print $0 " cats" }'
foo cats
または:
$ echo "foo\nbar\nbaz" | awk 'NR == 1 { print $0 " cats" }'
foo cats
- なぜどちらか一方を実行する必要があるのでしょうか?
- 別のツールを使うべきでしょうか?
- どのような要素を考慮すべきでしょうか?
- これらの要因をどのようにテストできますか?
答え1
この特定のケースでは、2 番目のオプションの方が適しています。
一般的に、パイプライン内のユーティリティの数を最小限に抑える方が効率的です。不要なプロセスをフォーク(開始)しないのが最善です(最初の例のように不要なプロセスsed
)。インターネットでは、次のような苦情の例を見つけるのは難しくありません。猫の無駄な使い方。
最近の Unix 系システム*のほとんどでは、フォークは非常に効率的に実行されますが、開始されるプロセスのサイズに依存します。たとえば、 または の起動はperl
またはよりpython
もはるかに遅くなります。sed
awk
一度限りのコマンドの場合、これはそれほど重要ではありませんが、パイプラインがループ内にあり、何度も実行される場合は、パイプラインから不要なプロセスを削除すると、全体の実行時間が大幅に短縮される可能性があります。
具体的な質問
なぜどちらか一方を実行する必要があるのでしょうか?
どちらか一方の構文に慣れている場合は、最も慣れているツール/言語を使用する方がコードの読みやすさ (および保守性) が向上する可能性があります。
別のツールを使うべきでしょうか?
この特定のケースでは、そうは思わない。 とawk
はどちらもsed
この種の仕事に適したツールです。
どのような要素を考慮すべきでしょうか?
複数のファイルを処理する必要がある場合(たとえば、ループ内)、速度と効率が重要になります。
時々 1 つの大きなファイルを処理するだけの場合は、コードの読みやすさがより重要になる可能性があります。
これらの要因をどのようにテストできますか?
Bash のシェル組み込みとして利用できるユーティリティを使用してtime
、さまざまなバージョンをプロファイルできます。また、スタンドアロンの実行可能プログラムとしても利用できます。たとえば、2 つのサンプル コマンドを実行すると、最初の例の方が 2 番目の例よりも 0.012 秒長くかかったことがわかります。
$ time echo "foo\nbar\nbaz" | sed 1q | awk '{ print $0 " cats" }'
foo\nbar\nbaz cats
real 0m0.056s
user 0m0.000s
sys 0m0.045s
$ time echo "foo\nbar\nbaz" | awk 'NR == 1 { print $0 " cats" }'
foo\nbar\nbaz cats
real 0m0.044s
user 0m0.000s
sys 0m0.031s
プロファイリング ベンチマークはシステム負荷やその他の制限要因の影響を受けるため、どのバージョンが他よりも高速であるかを正確に把握するには、これを何度も繰り返す必要があることに注意してください。
* MS Windowsでは、フォークはよりコストがかかるため、Cygwin などの環境で実行する場合には、開始されるプロセスの数を最小限に抑えることが効果的です。
答え2
使うだけで十分ですawk(またはsed) ツールはこのような単純なケースには適していません。複数のツールを組み合わせると、複雑になりすぎて冗長になることがよくあります。
echo -e "foo\nbar\nbaz" | awk 'NR==1{print $0" cats"}'
出力:
foo cats
どのような要素を考慮すべきでしょうか?
必要なテキスト処理には複数の異なるツールの組み合わせが必要であることを確認し、そうでない場合は1つの個別のツールの力を活用する
入力文字列の最初の単語の前に特定の単語を追加するだけの場合、これも簡単です。sed道具:
echo -e "foo\nbar\nbaz" | sed 's/^.*$/& cats/; 1q'
foo cats
echo -e
フラグ「e
バックスラッシュエスケープの解釈を有効にする」
いずれにせよ、入力テキストの複雑さとテキスト処理ルールの洗練度によって異なります。