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]} }
#!/bin/awk
您告訴 awk 使用包含腳本的文件的名稱作為腳本執行,而不是使用包含腳本的文件的內容。這就像寫:awk './delayed_by_day_jan20.awk'
代替:
awk -f './delayed_by_day_jan20.awk'
就像在命令行上指定一個包含 awk 腳本的文件一樣,您也必須
-f
在 shebang 中使用來告訴 awk 打開它傳遞的文件名(即目前腳本文件的名稱)並將其內容用作 awk 腳本解釋。話說回來….
將您在 Unix 中編寫的每個命令都視為一個命令。該命令是用 awk、perl、shell 還是其他任何東西編寫的都沒有關係——它應該根據它的作用來命名**,**而不是它的實現方式。鑑於此,您永遠不應該有以 or 結尾的命令,
.awk
或者.sh
其他.perl
任何指示它們編寫的語言的命令,以便除其他外,您可以將您在 awk 中編寫的任何命令重新實現為 perl,反之亦然必須通過呼叫該命令的所有其他命令來更改它們。所以你的命令名應該是delayed_by_day_jan20
,而不是delayed_by_day_jan20.awk
。此外,其他人不同意這一點,因為他們喜歡使用理解 awk 語法的編輯器,但是 IMO 你永遠不應該使用 shebang 來呼叫 awk,只需使用 shebang 來呼叫你使用的任何 shell,然後只需在你的 shell 腳本中呼叫 awk就像你從命令行呼叫它一樣。對於那些在 awk 中完成大部分工作但在 shell 中完成部分工作很有用的極其常見的情況,這將大大降低腳本的複雜性,例如驗證輸入文件的存在、創建臨時文件、設置陷阱、將命令參數分隔為awk 變數分配與 awk 參數等。有關這些問題的更多資訊,請參見https://stackoverflow.com/a/61002754/1745001和Google“awk shebang”。
以下是編寫 shell 腳本的方法:
$ 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 腳本以執行您希望它執行的任何操作(如果不是),並在您遇到問題時提出一個新問題。