awk で曜日別のパーセンテージを返す

awk で曜日別のパーセンテージを返す

CSV ファイルにフライトのデータセットがあり、遅延したフライトの割合 (列 6) を日別に取得したいと考えています。0 は遅延なし、1 は 15 分以上の遅延です。

入力:

DAY_OF_MONTH,"DAY_OF_WEEK","ORIGIN","DEST","DEP_TIME","DEP_DEL15","CANCELLED","DIVERTED","DISTANCE"
1,Tuesday,ORD,GRB,1003,0.00,0.00,0.00,322.248
1,Tuesday,TUL,ORD,1027,0.00,0.00,0.00,1083.42
1,Tuesday,EWR,TYS,1848,0.00,0.00,0.00,1168.61

出力:

Weekday, % delayed, delayed, total flights
Tuesday,0.00,0,3

データセットには実際には多数の行があり、月のすべての日とそのすべてのフライトが含まれているため、実際の出力にはなりません。

誰かが私を助けてくれました:

#!/bin/awk
BEGIN { FS = OFS = "," }
FNR > 1 { total[$2]++; if ($6) delay[$2]++ }
END {
    print "\"weekday\"", "\"percentage_delayed\"", "\"delayed\"", "\"total_flights\""
    for ( day in total ) { print day, delay[day] / total[day] * 100, delay[day], total[day]}

}

しかし、これを awk ファイルに保存して、次のように実行しようとすると、端末出力

答え1

#!/bin/awkawkに実行するように指示すると、名前スクリプトを含むファイルのコンテンツスクリプトを含むファイルの。次のように記述します。

awk './delayed_by_day_jan20.awk'

の代わりに:

awk -f './delayed_by_day_jan20.awk'    

コマンドラインで awk スクリプトを含むファイルを指定するのと同様に、-f渡されたファイル名 (つまり、現在のスクリプト ファイルの名前) を開き、その内容を awk スクリプトとして使用して解釈するように awk に指示するには、シェバンも使用する必要があります。

そうは言っても....

Unixで書くコマンドはすべてコマンドとして考えてください。そのコマンドがawk、perl、シェル、その他の言語で書かれているかどうかは関係ありません。コマンドはそれが何であるかに基づいて名前が付けられるべきです。するであり、それがどのように実装されているかではありません。したがって、.awk.sh.perlまたは記述言語を示すその他の文字で終わるコマンドは使用しないでください。そうすることで、とりわけ、そのコマンドを呼び出す他のすべてのコマンドを変更せずに、awk で記述したコマンドを perl に再実装したり、その逆を行ったりすることができます。したがって、コマンド名はdelayed_by_day_jan20ではなく にする必要がありますdelayed_by_day_jan20.awk

また、awk 構文を理解するエディタを使いたいのでこれに反対する人もいますが、私の意見では、shebang を使用して awk を呼び出すべきではありません。shebang を使用して使用するシェルを呼び出し、コマンドラインから呼び出すのと同じように、シェル スクリプト内で awk を呼び出すだけです。これにより、入力ファイルの存在の検証、一時ファイルの作成、トラップの設定、コマンド引数を awk 変数割り当てと awk 引数に分離するなど、ほとんどの作業を awk で実行し、一部をシェルで実行することが有用な非常に一般的なケースで、スクリプトの複雑さが大幅に軽減されます。https://stackoverflow.com/a/61002754/1745001そして「awk shebang」をグーグルで検索問題の詳細については、こちらをご覧ください。

シェル スクリプトの書き方は次のとおりです。

$ cat delayed_by_day_jan20
#!/usr/bin/env bash

awk '
BEGIN { FS = OFS = "," }
FNR > 1 { total[$2]++; if ($6) delay[$2]++ }
END {
    print "\"weekday\"", "\"percentage_delayed\"", "\"delayed\"", "\"total_flights\""
    for ( day in total ) {
        printf "%s,%0.2f,%d,%d\n", day, delay[day] / total[day] * 100, delay[day], total[day]
    }
}
' "${@:--}"

$ ./delayed_by_day_jan20 file
"weekday","percentage_delayed","delayed","total_flights"
Tuesday,0.00,0,3

これで、awk スクリプトを修正して、やりたいことを実行するだけで済みます。それがうまくいかない場合は、新しい質問をしてください。

関連情報