Perlのawk
ような自動分割オプションを使いたくなります。5つの列があります。3つには日付と時刻の情報が含まれ、次にサイズ、次に名前が含まれます。
私が書いたスクリプトの最初のバージョンも、最も冗長です。
perl -n -a -e '$total += $F[3]; $num++; END { printf "%12.2f\n", $total / ($num + 0.0); }'
(-a
自動分割)オプションは、空白の行を配列に分割します@F
。-n
オプション(各行を出力せずにファイル名引数を順番に読み取るループでPerlを実行する、または標準入力を実行する)と組み合わせると、コードは$F[3]
(0から数えて4番目の列)をに追加します$total
。これは自動的に初期化されます。最初の使用ではゼロ。また、の行をカウントし$num
ます。END
ブロックは、すべての入力が読み取られたときに実行されます。printf()
値をフォーマットするために使用します。は+ 0.0
、整数演算ではなく、浮動小数点で演算が行われることを保証します。これはawk
スクリプトと非常によく似ています。
awk '{ total += $4 } END { print total / NR }'
プログラムの最初のドラフトが最適になることはめったにありません。少なくとも、私はそれほど優れたプログラマーではありません。改訂が役立ちます。
Perlは、部分的にはawk
キラーとして設計されました。a2p
スクリプトをPerlに変換するためのPerlで配布されたプログラムがまだありますawk
(そしてスクリプトをPerlに変換するためのプログラムもありs2p
ますsed
)。また、Perlには、読み取られた行数を追跡する自動(組み込み)変数があります。いくつかの名前があります。tersestは$.
; スクリプトを使用して$NR
いる場合は、ニーモニック名を使用できます。use English;
です$INPUT_LINE_NUMBER
。したがって、使用$num
する必要はありません。また、Perlはとにかく浮動小数点除算を行うので、その+ 0.0
部分は不要でした。これは次のバージョンにつながります:
perl -MEnglish -n -a -e '$total += $F[3]; END { printf "%12.2f\n", $total / $NR; }'
また:
perl -n -a -e '$total += $F[3]; END { printf "%12.2f\n", $total / $.; }'
あなたの気まぐれや空想に合うように印刷フォーマットを調整することができます。これは基本的に、私が長期的に使用するスクリプトです。それは決して長蛇の列がなくてもかなり明確です。必要に応じて、スクリプトを複数の行に分割することもできます。IMNSHOさん、1行の読みやすさは問題にならないほど簡単な作業です。split
そして、これの美しさは、配列やループを自分でいじくり回す必要がないことです。Perlはそのほとんどをあなたに代わって行います。(確かに、空の入力で爆発します。その修正は簡単です。以下を参照してください。)
推奨バージョン
perl -n -a -e '$total += $F[3]; END { printf "%12.2f\n", $total / $. if $.; }'
読み取られたif $.
行数がゼロかどうかをテストします。がゼロの場合、printf
および除算は省略さ$.
れるため、入力がない場合、スクリプトは何も出力しません。
Stack Overflowの初期によくプレイされていた、「コードゴルフ」と呼ばれる高貴な(または無視できる)ゲームがありますが、コードゴルフの質問はもはや良い質問とは見なされていません。コードゴルフの目的は、特定のタスクを可能な限り少ない文字で実行するプログラムを作成することです。これを使用してコードゴルフをプレイし、出力の形式についてあまり心配せず、少なくともPerl 5.10を使用している場合は、さらに圧縮することができます。
perl -Mv5.10 -n -a -e '$total += $F[3]; END { say $total / $. if $.; }'
そして、明らかに、そこには不要なスペースや文字がたくさんあります。
perl -Mv5.10 -nae '$t+=$F[3];END{say$t/$.if$.}'
ただし、これは推奨バージョンほど明確ではありません。