Comprensión de archivos AWK y CSV
¿Cómo puedo escribir un programa AWK que analice una lista de campos en archivos CSV, cuente el número de cada cadena diferente en el campo especificado e imprima el recuento de cada cadena que se encuentra? Solo he codificado en C y Java, por lo que estoy completamente confundido con la sintaxis de AWK. Entiendo los conceptos más simples, sin embargo, AWK está estructurado de manera muy diferente. Cualquier momento es apreciado, ¡gracias!
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]
}
En un archivo CSV que contiene:
Field1, Field2, Field3, Field4
A, B, C, D
A, E, F, G
Z, E, C, D
Z, W, C, Q
Puedo obtener el resultado:
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
Este es el resultado deseado:
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
Hay una edición en mi código que está comentada.
Respuestas
Corregido tu código:
$ 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
Salida (usando GNU awk. Otros awks muestran la salida en diferente orden):
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 realmente no es la herramienta adecuada para este trabajo. Si bien AWK puede interpretar datos separados por comas o tabulaciones, no tiene el concepto de recintos de campo o escapes. Entonces podría manejar un ejemplo simple como:
Month,Day
January,Sunday
February,Monday
pero fallaría con este ejemplo válido:
Month,Day
January,"Sunday"
February,"Monday"
Por eso, recomendaría considerar otro idioma. Algo como 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 incluso 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