Gibt es einen Befehlszeilen-Spruch, um eine Spalte in einer CSV-Datei abzulegen?

32

Eine Datei mit folgendem Inhalt haben:

1111,2222,3333,4444
aaaa,bbbb,cccc,dddd

Ich versuche, eine Datei zu erhalten, die der Originaldatei entspricht, aber keine n-te Spalte wie für n = 2 (oder 3) hat.

1111,2222,4444
aaaa,bbbb,dddd

oder, für n = 0 (oder kann es 1 sein)

2222,3333,4444
bbbb,cccc,dddd

Eine echte Datei kann Gigabyte lang sein und zehntausende Spalten haben.

Wie immer in solchen Fällen vermute ich, dass Kommandozeilenmagier eine elegante Lösung anbieten können ... :-)

In meinem eigentlichen Fall muss ich 2 erste Spalten löschen, was durch zweimaliges Löschen einer ersten Spalte in einer Sequenz geschehen kann, aber ich nehme an, es wäre interessanter, ein wenig zu verallgemeinern.

Ivan
quelle
Sind die Felder garantiert nicht enthalten ,? (Dh, ,wird immer nur als Feldtrennzeichen verwendet.)
CVn
@ MichaelKjörling, es wäre schön, eine flexiblere Lösung zu haben, aber in meinem Fall - ja: das Trennzeichen ist ,und kommt nie innerhalb eines Feldes vor.
Ivan
In diesem Fall sollte Scotts Antwort genau das Richtige sein.
ein Lebenslauf vom

Antworten:

47

Ich glaube, das ist spezifisch, um aus den GNU-Coreutils zu schneiden:

$ cut --complement -f 3 -d, inputfile
1111,2222,4444
aaaa,bbbb,dddd

Normalerweise geben Sie die gewünschten Felder mit -f an, aber durch Hinzufügen von --complement kehren Sie natürlich die Bedeutung um. Aus "Mann geschnitten":

--complement
    complement the set of selected bytes, characters or fields

Eine Einschränkung: Wenn eine der Spalten ein Komma enthält, wird der Wert abgeschnitten, da cut kein CSV-Parser ist, wie es eine Kalkulationstabelle ist. Viele Parser haben unterschiedliche Vorstellungen zum Umgang mit Kommas in CSV. Für den einfachen CSV-Fall ist cut in der Befehlszeile immer noch der richtige Weg.

Scott McClung
quelle
4
Das funktioniert gut, solange es sich um eine einfache CSV-Datei handelt. Wenn eine der Spalten eine Zeichenfolge mit einem Komma ist, wird sie verworfen, cutda es sich nicht um einen CSV-Parser handelt. Wenn ein CSV-Feld ein Feldtrennzeichen enthält, wird es in Anführungszeichen gesetzt. Übrigens, zum Thema cut, -fnimmt Feldbereiche. cut -f, -d3-gibt das dritte Feld an aus und entfernt die ersten beiden.
Alexios
2
Du meinstcut -d, -f3-
Nutzlos
@ Alexios das ist ein guter Punkt. Ich habe nie wirklich mit "echtem" CSV zu tun, nur mit der einfachen Teilmenge. Ich werde meine Antwort entsprechend anpassen.
Scott McClung
@Useless: Verdammt ja. Das nenne ich meine "geschnittene Legasthenie" wieder auffällig. Seufzer . Scott: CSV-Dateien sind knifflige Biester. Viel zu viele verschiedene Unterformate, von denen einige nicht einmal C SV sind, aber üblicherweise sowieso so genannt werden.
Alexios
Dadurch wird die neue CSV auf meinem Terminal gedruckt. Wie kann ich sie dazu bringen, die Eingabe zu überschreiben (oder möglicherweise in eine neue Datei zu schreiben, nach der OP anscheinend gesucht hat)?
Max Ghenis
12

Wenn die Daten einfach aus durch Kommas getrennten Spalten bestehen:

cut -d , -f 1-2,4-

Sie können auch awk verwenden, dies ist jedoch etwas umständlich, da das Entfernen des Trennzeichens einige Arbeit kostet, während das Löschen eines Feldes einfach ist. Wenn Sie kein leeres Feld haben, ist es nicht so schlimm:

awk -F , 'BEGIN {OFS=FS}  {$3=""; sub(",,", ","); print}'

Wenn Sie eine tatsächliche CSV-Datei haben, in der Kommas in Feldern angezeigt werden können, benötigen Sie eine echte CSV-Bibliothek .

Gilles 'SO - hör auf böse zu sein'
quelle