Grundlegendes zu AWK- und CSV-Dateien
Wie kann ich ein AWK-Programm schreiben, das eine Liste von Feldern in CSV-Dateien analysiert, die Anzahl der verschiedenen Zeichenfolgen im angegebenen Feld zählt und die Anzahl der gefundenen Zeichenfolgen ausdrucken? Ich habe nur in C und Java codiert, daher bin ich völlig verwirrt über die Syntax von AWK. Ich verstehe das einfachste Konzept, aber AWK ist sehr unterschiedlich strukturiert. Jederzeit wird geschätzt, danke!
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 einer CSV-Datei mit:
Field1, Field2, Field3, Field4
A, B, C, D
A, E, F, G
Z, E, C, D
Z, W, C, Q
Ich kann das Ergebnis erhalten:
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
Dies ist das gewünschte Ergebnis:
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
Mein Code wurde bearbeitet und kommentiert.
Antworten
Ihr Code wurde korrigiert:
$ 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
Ausgabe (mit GNU awk. Andere awks zeigten die Ausgabe in anderer Reihenfolge an):
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 ist wirklich nicht das richtige Werkzeug für diesen Job. AWK kann zwar durch Kommas oder Tabulatoren getrennte Daten interpretieren, hat jedoch kein Konzept für Feldumhüllungen oder Escapezeichen. So könnte es ein einfaches Beispiel behandeln wie:
Month,Day
January,Sunday
February,Monday
würde aber mit diesem gültigen Beispiel scheitern:
Month,Day
January,"Sunday"
February,"Monday"
Aus diesem Grund würde ich empfehlen, eine andere Sprache in Betracht zu ziehen. So etwas wie Python:
import csv
o = open('a.csv')
for m in csv.DictReader(o):
print(m)
https://docs.python.org/library/csv.html
Oder Ruby:
require 'csv'
CSV.table('a.csv').each do |m|
p m
end
https://ruby-doc.org/stdlib/libdoc/csv/rdoc/CSV.html
Oder sogar 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