Comprendre les fichiers AWK et CSV

Oct 20 2020

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

1 JamesBrown Oct 21 2020 at 03:35

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

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