Comprensione dei file AWK e CSV

Oct 20 2020

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

1 JamesBrown Oct 21 2020 at 03:35

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
StevenPenny Oct 21 2020 at 03:10

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