Extrahieren Sie Daten aus einer Datei und platzieren Sie sie basierend auf einem Spaltenwert in verschiedenen Dateien


13

Wir werden eine CSV-Datei mit folgenden Werten erstellen

yp1234,577,1,3
yp5678,577,3,5
yp9012,132,8,9

Ich muss Daten extrahieren und Dateien basierend auf der zweiten Spalte erstellen. Wenn es 577 ist, muss die gesamte Zeile extrahiert und in einer separaten Datei abgelegt werden. Ich meine, ich brauche eine Datei mit Zeilen mit der zweiten Spalte als 577 allein und eine andere Datei mit der zweiten Spalte als 132 allein

Ich habe versucht, IF zu verwenden, aber es hat nicht funktioniert


5
Es ist immer eine gute Idee, den Code zu veröffentlichen, der nicht funktioniert.
Goldlöckchen

Antworten:


26

Verwendung awk:

awk -F, '{ print > $2 ".csv" }' file.csv

Dadurch werden die beiden Dateien erstellen 577.csvund 132.csvin Ihrem aktuellen Verzeichnis.

Der obige Befehl setzt voraus, dass Sie nur 132oder 577als zweites Feld haben können. Es wird ein Dateiname für jeden der Werte erstellt, die im zweiten Feld des gesamten Felds gefunden werden file.csv.

Wenn es außer den beiden Werten noch andere Werte gibt, die Sie interessieren, und Sie diese Zeilen ignorieren möchten, gehen Sie stattdessen wie folgt vor:

awk -F, '$2 == "577" || $2 == "132" { print > $2 ".csv" }' file.csv

1
Es gibt fehlerhafte awkImplementierungen, die nicht verwendet werden können print > $2 ".cvs". Auf diejenigen, würden Sie die Dateinamen zum ersten Rechen haben, dann tut das print: fname = $2 ".cvs"; print > fname.
Kusalananda

3

Ich mag die awkLösung von Terdon , aber der Vollständigkeit halber hier nur ein Vorschlagbash

while IFS=, read -r a1 a2 a3 a4; do 
    echo "$a1,$a2,$a3,$a4" >> "$a2".csv
done < file.csv

Es werden Dateien 577.csvund 132.csvim aktuellen Verzeichnis erstellt.


3

Alle 577 auf stdout extrahieren

grep -e '^.*,577,.*,.*$' youfile.csv >result_extract_557.csv

- Bearbeiten Sie 1 Korrigiert, basierend auf @ terdons Kommentar unten, um falsche Übereinstimmungen zu vermeiden, wenn mindestens 3 Kommas mit 577 übereinstimmen.

grep -e '^[:alnum:]*,577,[:digit:]*,[:digit:]*$' youfile.csv >result_extract_557.csv

Aber ich denke, seine / ihre awkLösung ist umfassender.


Dies wird auch dann zutreffen, wenn 577 sich auf einem anderen Feld befindet, nicht auf dem zweiten, oder wenn es Teil eines Feldes ist. Zum Beispiel foo577baroder yp9012,132,8,577.
Terdon

Ich dachte, meine Kommas würden es abhängig von der Feldposition machen?
X Tian

Leider habe ich schlechte Beispiele angegeben, aber die .*können auch mit Kommas übereinstimmen, sodass Sie nicht wissen, welches Feld Sie abgleichen. Könnte der zweite sein, könnte auch der 45. sein. Meine zweite Beschwerde war falsch, Sie haben Recht, dass die Kommas vor Übereinstimmungen schützen foo577bar.
terdon

was tun wenn | Zeichen wird anstelle von, verwendet.
user3116123

Empfang unter Fehler grep: illegale Option - e Verwendung: grep -hblcnsviw Musterdatei. . .
user3116123

1

Verwenden von csvkit:

$ csvgrep -c 2 -m 577 data.csv >output.csv

Die -c 2Marken cvsgrepberücksichtigen die zweite Spalte, und -m 577wir bitten sie, mit der Zeichenfolge 577in dieser Spalte übereinzustimmen.

Folgendes wird geschrieben an output.csv:

yp1234,577,1,3
yp5678,577,3,5

So passen Sie mehrere Zeichenfolgen an und schreiben die Ausgabe für jede Zeichenfolge in eine Datei:

for pattern in 577 132; do
  csvgrep -c 2 -m "$pattern" data.csv >"output-$pattern.csv"
done

Dadurch werden die beiden Dateien output-132.csvund erstellt output-577.csv.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.