awk para retornar porcentagem por dia da semana

awk para retornar porcentagem por dia da semana

Portanto, tenho um conjunto de dados de voos em um arquivo CSV e quero obter uma porcentagem de voos atrasados ​​(coluna 6) ordenados por dia. 0 é para não atrasado e 1 é para atraso de 15 minutos ou mais.

Entrada:

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

Saída:

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

Na verdade, o conjunto de dados tem muitas linhas e todos os dias do mês e todos os seus voos, então essa não seria a saída real.

Alguém me ajudou a pensar em:

#!/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]}

}

Mas quando eu salvo isso em um arquivo awk e tento executá-lo com:Saída terminal

Responder1

Com #!/bin/awkvocê está dizendo ao awk para executar usando onomedo arquivo que contém o script como o script em vez doconteúdodo arquivo que contém o script. É como escrever:

awk './delayed_by_day_jan20.awk'

em vez de:

awk -f './delayed_by_day_jan20.awk'    

Assim como especificar um arquivo contendo um script awk na linha de comando, você -ftambém deve usar um shebang para dizer ao awk para abrir o nome do arquivo que foi passado (ou seja, o nome do arquivo de script atual) e usar seu conteúdo como o script awk interpretar.

Tendo dito isto....

Considere cada comando que você escreve no Unix como apenas um comando. Não importa se esse comando está escrito em awk, perl, shell ou qualquer outra coisa - ele deve ser nomeado com base no quefaz, não como é implementado. Dado isso, você nunca deve ter comandos que terminem em .awkou .shou .perlqualquer outra coisa que indique o idioma em que foram escritos, para que, entre outras coisas, você possa reimplementar qualquer comando que escreveu em awk para perl ou vice-versa sem ter que passar por todos os outros comandos que chamam esse comando para alterá-los. Portanto, o nome do seu comando deve ser delayed_by_day_jan20, não delayed_by_day_jan20.awk.

Além disso, outros discordam disso porque gostam de usar um editor que entenda a sintaxe do awk, mas IMO, você nunca deve usar um shebang para chamar o awk, apenas use o shebang para chamar qualquer shell que você usar e então simplesmente chame o awk dentro do seu shell script apenas como você chamaria na linha de comando. Isso reduzirá bastante a complexidade dos seus scripts para aqueles casos extremamente comuns onde é útil fazer a maior parte do trabalho no awk, mas também partes dele no shell, por exemplo, validar a existência de arquivos de entrada, criar arquivos temporários, definir armadilhas, separar argumentos de comando em atribuições de variáveis ​​​​awk vs argumentos awk, etc., etc.https://stackoverflow.com/a/61002754/1745001egoogle "awk shebang"para obter mais informações sobre os assuntos.

Veja como escrever seu script de 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

Agora apenas corrija seu script awk para fazer o que você deseja, se não for isso, e faça uma nova pergunta se tiver problemas para fazer isso.

informação relacionada