Grundlegendes zu AWK- und CSV-Dateien

Oct 20 2020

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

1 JamesBrown Oct 21 2020 at 03:35

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

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