Comprensione dei file AWK e CSV
Come posso scrivere un programma AWK che analizzi un elenco di campi nei file CSV, contare il numero di ogni stringa diversa nel campo specificato e stampare il conteggio di ogni stringa trovata? Ho solo codificato in C e Java, quindi sono completamente confuso sulla sintassi di AWK. Capisco il più semplice dei concetti, tuttavia, AWK è strutturato in modo molto diverso. Ogni momento è apprezzato, grazie!
BEGIN {
FS = ""
}
{
for(i = 1; i <= NF; i++)
freq[$i]++
PROCINFO ["sorted_in"] = "@val_num_desc" #this got the desired result
}
END {
for {this in freq)
printf "%s\t%d\n", this, freq[this]
}
In un file CSV contenente:
Field1, Field2, Field3, Field4
A, B, C, D
A, E, F, G
Z, E, C, D
Z, W, C, Q
Sono in grado di ottenere il risultato:
A 2
B 1
C 3
Q 1
D 1
E 2
F 1
, 12
G 1
W 1
Field1,Field2,Field3,Field4 1
Z 2
Questo è il risultato desiderato:
A 10
C 7
D 2
E 2
Z 2
B 1
Q 1
Field1 1
Field2 1
F 1
Field3 1
G 1
Field4 1
W 1
C'è una modifica al mio codice che è commentata.
Risposte
Risolto il tuo codice:
$ awk ' BEGIN { # you need BEGIN block for FS FS = ", *" # your data had ", " and "," seps } # ... based on your sample output { for(i = 1; i <= NF; i++) freq[$i]++
}
END {
for(this in freq) # fixed a parenthesis
printf "%s\t%d\n", this, freq[this]
}' file
Output (utilizzando GNU awk. Altri awk hanno visualizzato l'output in ordine diverso):
A 2
B 1
C 3
Q 1
D 2
Field1 1
E 2
Field2 1
F 1
Field3 1
G 1
Field4 1
W 1
Z 2
AWK non è davvero lo strumento giusto per questo lavoro. Sebbene AWK possa interpretare dati separati da virgole o tabulazioni, non ha il concetto di racchiudi di campo o di escape. Quindi potrebbe gestire un semplice esempio come:
Month,Day
January,Sunday
February,Monday
ma fallirebbe con questo esempio valido:
Month,Day
January,"Sunday"
February,"Monday"
Per questo motivo, consiglierei di considerare un'altra lingua. Qualcosa come Python:
import csv
o = open('a.csv')
for m in csv.DictReader(o):
print(m)
https://docs.python.org/library/csv.html
O Ruby:
require 'csv'
CSV.table('a.csv').each do |m|
p m
end
https://ruby-doc.org/stdlib/libdoc/csv/rdoc/CSV.html
O anche PHP:
<?php
$r = fopen('a.csv', 'r'); $a_head = fgetcsv($r); while (true) { $a_row = fgetcsv($r); if (feof($r)) {
break;
}
$m_row = array_combine($a_head, $a_row); print_r($m_row);
}
https://php.net/function.fgetcsv