@MaxMackie askubuntu.com/questions/88142/… . Ich kann dort in dieser Stunde keinen Mod finden, also habe ich ihn markiert und sie gebeten, zu migrieren, wenn sie wollen. Es hat bereits eine akzeptierte Antwort, daher bin ich mir nicht sicher, ob sie es werden
Michael Mrozek
@MichaelMrozek, hmmm was passiert normalerweise in diesen Situationen? Bewahren wir die Duplikate einfach auf?
Abgesehen davon, wie Sie die Felder ausschneiden und neu anordnen (siehe die anderen Antworten), gibt es auch das Problem der skurrilen CSV-Felder.
Wenn Sie Ihre Daten in dieser „quirky“ Kategorie fällt, ein bisschen vor und Post - Filterung kann sich darum kümmern. Die Filter unten erfordern die Zeichen \x01, \x02, \x03, \x04nicht überall in Ihren Daten erscheinen.
Hier sind die Filter, die um einen einfachen Feldspeicherauszug gewickelt sind awk.
Hinweis: Feld 5 hat ein ungültiges / unvollständiges Layout für Felder in Anführungszeichen, ist jedoch am Ende einer Zeile harmlos (abhängig vom CSV-Parser). Aber natürlich wäre es verursacht problematisch unexpedted Ergebnisse , wenn sie von ihrem aktuellen werden sollten getauscht weg End-of-Row - Position.
Aktualisieren; user121196 hat auf einen Fehler hingewiesen, wenn vor einem nachgestellten Anführungszeichen ein Komma steht. Hier ist die Lösung.
Die Daten
cat <<'EOF'>file
field one,"fie,ld,two",field"three","field,\",four","field,five
"15111 N. Hayden Rd., Ste 160,",""
EOF
field one
"fie,ld,two"
field"three""field,\",four""field,five
"15111 N. Hayden Rd., Ste 160,"""
Hier ist der Vorfilter , erweitert mit Kommentaren.
Der Nachfilter ist nur eine Umkehrung von \x01. \x02, \x03,\x04
sed -r '
s/^/,/# add a leading comma delimiter
s/\\"/\x01/g # obfuscate escaped quotation-mark (\")
s/,"([^"]*)"/,\x02\1\x03/g # obfuscate quotation-marks
s/,"/,\x02/# when no trailing quote on last field :MC # obfuscate commas embedded in quotes
s/\x02([^\x03]*),([^\x03]*)/\x02\1\x04\2/g
tMC
s/^,// # remove spurious leading delimiter'
Wie würden Sie die n-te Spalte basierend auf diesem Filter löschen?
user121196
@ user121196 - Wie im ersten Satz erwähnt, zeigt diese Antwort eine Möglichkeit, die CSV-Daten konsistenter zu machen. indem Sie ein in Anführungszeichen eingebettetes Komma vorübergehend durch ein neutrales Token-Zeichen ersetzen ... und es nach dem Verschieben / Ausschneiden / Löschen wieder in ein Komma umwandeln. Wie bereits erwähnt, wird der Schritt Verschieben / Ausschneiden / Löschen durch einen einfachen awk-Field-Dump ersetzt .
Peter.O
1
In diesem Fall schlägt dies fehl: "15111 N. Hayden Rd., Ste 160,", ""
user121196
@ user121196: Danke für den Hinweis. Ich habe die Antwort mit einem Update aktualisiert.
Peter.O
15
Dies hängt davon ab, ob Ihre CSV-Datei Kommas nur für Trennzeichen verwendet oder ob Sie den Wahnsinn haben:
Feld eins, "Feld zwei", Feld drei
Dies setzt voraus, dass Sie eine einfache CSV-Datei verwenden:
Eine Spalte entfernen
Sie können eine einzelne Spalte auf viele Arten loswerden. Ich habe als Beispiel Spalte 2 verwendet. Am einfachsten ist wahrscheinlich die Verwendung cut, mit der Sie ein Trennzeichen angeben -dund welche Felder Sie drucken möchten -f. Dies teilt es in Kommas und Ausgabefeld 1 und die Felder 3 bis zum Ende auf:
$ cut -d,-f1,3-/path/to/your/file
Wenn Sie tatsächlich verwenden müssen sed, können Sie einen regulären Ausdruck schreiben, der mit den ersten n-1Feldern, dem nth-Feld und dem Rest übereinstimmt , und die Ausgabe des nth -Felds überspringen (hier nist 2, damit die erste Gruppe nach 1Zeit abgeglichen wird:) \{1\}:
$ sed 's/\(\([^,]\+,\)\{1\}\)[^,]\+,\(.*\)/\1\3/'/path/to/your/file
Dafür gibt es eine Reihe von Möglichkeiten awk, von denen keine besonders elegant ist. Sie können eine forSchleife verwenden, aber mit dem nachgestellten Komma umzugehen ist ein Schmerz; ignorieren, dass es so etwas wie wäre:
Da es sich um CSV handelt, benötigen Sie auch BEGIN { FS=","; OFS=","; }.
1
Ich denke sogar FS = OFS = "," wird funktionieren.
5
Gegeben sei eine durch Leerzeichen getrennte Datei im folgenden Format:
12345
Sie können Feld 2 mit awk wie folgt entfernen:
awk '{ sub($2,""); print}' file
was zurückkehrt
1345
Ersetzen Sie Spalte 2 gegebenenfalls durch Spalte n.
So duplizieren Sie Spalte 2:
awk '{ col = $2 " " $2; $2 = col; print }' file
was zurückkehrt
122345
So wechseln Sie zwischen Spalte 2 und 3:
awk '{temp = $2; $2 = $3; $3 = temp; print}'
was zurückkehrt
13245
awk ist generell sehr gut im Umgang mit dem Feldbegriff . Wenn Sie mit einer CSV-Datei und nicht mit einer durch Leerzeichen getrennten Datei arbeiten, können Sie sie einfach verwenden
awk -F,
Definieren Sie Ihr Feld als Komma anstelle eines Leerzeichens (dies ist die Standardeinstellung). Es gibt eine Reihe guter awk-Ressourcen online, von denen ich eine unten als Quelle aufführe.
Ich weiß nicht viel darüber awk, aber es scheint eine durch Leerzeichen getrennte Ausgabe zu geben, auch wenn das Feldtrennzeichen ,(das Feldtrennzeichen steuert nur, wie es die Eingabe behandelt)
Michael Mrozek
@MichaelMrozek: Ja, es ist die OFS awk-Variable, die das Ausgabefeldtrennzeichen steuert.
Enzotib
Ja, und wie ich in meiner Antwort erwähne, können Sie die Option -F an awk übergeben, um das Trennzeichen (z. B. -F,)
Antworten:
Abgesehen davon, wie Sie die Felder ausschneiden und neu anordnen (siehe die anderen Antworten), gibt es auch das Problem der skurrilen CSV-Felder.
Wenn Sie Ihre Daten in dieser „quirky“ Kategorie fällt, ein bisschen vor und Post - Filterung kann sich darum kümmern. Die Filter unten erfordern die Zeichen
\x01
,\x02
,\x03
,\x04
nicht überall in Ihren Daten erscheinen.Hier sind die Filter, die um einen einfachen Feldspeicherauszug gewickelt sind
awk
.Hinweis: Feld 5 hat ein ungültiges / unvollständiges Layout für Felder in Anführungszeichen, ist jedoch am Ende einer Zeile harmlos (abhängig vom CSV-Parser). Aber natürlich wäre es verursacht problematisch unexpedted Ergebnisse , wenn sie von ihrem aktuellen werden sollten getauscht weg End-of-Row - Position.
Aktualisieren; user121196 hat auf einen Fehler hingewiesen, wenn vor einem nachgestellten Anführungszeichen ein Komma steht. Hier ist die Lösung.
Die Daten
Der Code
Die Ausgabe:
Hier ist der Vorfilter , erweitert mit Kommentaren.
Der Nachfilter ist nur eine Umkehrung von
\x01
.\x02
,\x03
,\x04
quelle
Dies hängt davon ab, ob Ihre CSV-Datei Kommas nur für Trennzeichen verwendet oder ob Sie den Wahnsinn haben:
Dies setzt voraus, dass Sie eine einfache CSV-Datei verwenden:
Eine Spalte entfernen
Sie können eine einzelne Spalte auf viele Arten loswerden. Ich habe als Beispiel Spalte 2 verwendet. Am einfachsten ist wahrscheinlich die Verwendung
cut
, mit der Sie ein Trennzeichen angeben-d
und welche Felder Sie drucken möchten-f
. Dies teilt es in Kommas und Ausgabefeld 1 und die Felder 3 bis zum Ende auf:Wenn Sie tatsächlich verwenden müssen
sed
, können Sie einen regulären Ausdruck schreiben, der mit den erstenn-1
Feldern, demn
th-Feld und dem Rest übereinstimmt , und die Ausgabe desn
th -Felds überspringen (hiern
ist 2, damit die erste Gruppe nach1
Zeit abgeglichen wird:)\{1\}
:Dafür gibt es eine Reihe von Möglichkeiten
awk
, von denen keine besonders elegant ist. Sie können einefor
Schleife verwenden, aber mit dem nachgestellten Komma umzugehen ist ein Schmerz; ignorieren, dass es so etwas wie wäre:Ich finde es einfacher, Feld 1 auszugeben und dann
substr
alles nach Feld 2 abzurufen:Dies ist jedoch für weiter entfernte Kolumnen ärgerlich
Eine Spalte duplizieren
In
sed
dieser ist im Wesentlichen der gleiche Ausdruck wie zuvor, aber Sie auch die Zielspalt erfassen und umfassen die Gruppe mehrfach in dem Ersatz:In
awk
der for-Schleife wäre es so etwas wie (wieder ohne das nachstehende Komma):Der
substr
Weg:(tcdyl hat in seiner Antwort eine bessere Methode gefunden )
Eine Spalte verschieben
Ich denke, die
sed
Lösung folgt natürlich aus den anderen, aber es wird langsam lächerlich langquelle
awk
ist Ihre beste Wette.awk
druckt Felder nach Nummer, also ...So entfernen Sie eine Spalte, ohne sie zu drucken:
So ändern Sie die Reihenfolge:
Umleiten in eine Ausgabedatei.
awk
kann auch die Ausgabe formatieren.Ausgabe im Awk-Format
quelle
BEGIN { FS=","; OFS=","; }
.Gegeben sei eine durch Leerzeichen getrennte Datei im folgenden Format:
Sie können Feld 2 mit awk wie folgt entfernen:
was zurückkehrt
Ersetzen Sie Spalte 2 gegebenenfalls durch Spalte n.
So duplizieren Sie Spalte 2:
was zurückkehrt
So wechseln Sie zwischen Spalte 2 und 3:
was zurückkehrt
awk ist generell sehr gut im Umgang mit dem Feldbegriff . Wenn Sie mit einer CSV-Datei und nicht mit einer durch Leerzeichen getrennten Datei arbeiten, können Sie sie einfach verwenden
Definieren Sie Ihr Feld als Komma anstelle eines Leerzeichens (dies ist die Standardeinstellung). Es gibt eine Reihe guter awk-Ressourcen online, von denen ich eine unten als Quelle aufführe.
Quelle für # 3
quelle
awk
, aber es scheint eine durch Leerzeichen getrennte Ausgabe zu geben, auch wenn das Feldtrennzeichen,
(das Feldtrennzeichen steuert nur, wie es die Eingabe behandelt)Dies funktioniert zum Löschen
Eingang
Ausgabe
quelle