Comprendre les fichiers AWK et CSV
Comment puis-je écrire un programme AWK qui analyse une liste de champs dans des fichiers CSV, compter le nombre de chaque chaîne différente dans le champ spécifié et imprimer le nombre de chaque chaîne trouvée? Je n'ai codé qu'en C et Java, donc je suis complètement confus sur la syntaxe d'AWK. Je comprends le plus simple des concepts, cependant, AWK est structuré très différemment. Tout moment est apprécié, merci!
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]
}
Sur un fichier CSV contenant:
Field1, Field2, Field3, Field4
A, B, C, D
A, E, F, G
Z, E, C, D
Z, W, C, Q
Je suis en mesure d'obtenir le résultat:
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
Voici le résultat souhaité:
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
Il y a une modification de mon code qui est commentée.
Réponses
Correction de votre code:
$ 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
Sortie (en utilisant GNU awk. D'autres awks affichent la sortie dans un ordre différent):
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 n'est vraiment pas le bon outil pour ce travail. Bien qu'AWK puisse interpréter des données séparées par des virgules ou des tabulations, il n'a pas de concept de zones fermées ou d'échappement. Ainsi, il pourrait gérer un exemple simple comme:
Month,Day
January,Sunday
February,Monday
mais échouerait avec cet exemple valide:
Month,Day
January,"Sunday"
February,"Monday"
Pour cette raison, je recommanderais d'envisager une autre langue. Quelque chose comme Python:
import csv
o = open('a.csv')
for m in csv.DictReader(o):
print(m)
https://docs.python.org/library/csv.html
Ou Ruby:
require 'csv'
CSV.table('a.csv').each do |m|
p m
end
https://ruby-doc.org/stdlib/libdoc/csv/rdoc/CSV.html
Ou même 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