Sie haben eine Datei mit folgendem Inhalt:
1111,2222,3333,4444
aaaa,bbbb,cccc,dddd
Ich möchte eine Datei erhalten, die dem Original entspricht, in der aber eine n-te Spalte fehlt, z. B. für n = 2 (oder kann es auch 3 sein)
1111,2222,4444
aaaa,bbbb,dddd
oder für n = 0 (oder kann es auch 1 sein)
2222,3333,4444
bbbb,cccc,dddd
Eine echte Datei kann mehrere Gigabyte groß sein und Zehntausende Spalten haben.
Wie immer in solchen Fällen vermute ich, dass Kommandozeilen-Zauberer eine elegante Lösung anbieten können … :-)
In meinem tatsächlichen realen Fall muss ich zwei erste Spalten löschen, was dadurch erreicht werden kann, dass man eine erste Spalte zweimal hintereinander löscht, aber ich denke, es wäre interessanter, ein wenig zu verallgemeinern.
Antwort1
Ich glaube, dies gilt speziell für Cut aus den GNU-Coreutils:
$ 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 die Bedeutung natürlich um. Aus 'man cut':
--complement
complement the set of selected bytes, characters or fields
Eine Einschränkung: Wenn eine der Spalten ein Komma enthält, wird „cut“ ausgegeben, da „cut“ kein CSV-Parser im gleichen Sinne wie eine Tabellenkalkulation ist. Viele Parser haben unterschiedliche Vorstellungen davon, wie mit dem Escapen von Kommas in CSV umgegangen werden soll. Für den einfachen CSV-Fall ist „cut“ auf der Befehlszeile immer noch die beste Methode.
Antwort2
Wenn die Daten einfach aus durch Kommas getrennten Spalten bestehen:
cut -d , -f 1-2,4-
Sie können auch awk verwenden, aber das ist etwas umständlich, denn während das Löschen eines Felds einfach ist, ist das Entfernen des Trennzeichens etwas Arbeit. Wenn Sie kein leeres Feld haben, ist es nicht so schlimm:
awk -F , 'BEGIN {OFS=FS} {$3=""; sub(",,", ","); print}'
Wenn Sie eine echte CSV-Datei haben, in der Kommas innerhalb von Feldern erscheinen können, wenn sie richtig zitiert werden, benötigen Sie eineechte CSV-Bibliothek.
Antwort3
Verwenden eines CSV-fähigen Tools zum Entfernen der ersten beiden Spalten aus einer CSV-Eingabedatei ohne Kopfzeile:
$ cat file
1111,2222,3333,4444
aaaa,bbbb,cccc,dddd
$ mlr --csv -N cut -x -f 1,2 file
3333,4444
cccc,dddd
Die -x
Option zur cut
Operation inMüller( mlr
) bewirkt, dass die Operationausschließendie benannten Felder (in diesem Fall die Felder Nummer 1 und 2). Hätten die CSV-Daten Überschriften gehabt, hätten wir benannte Felder verwenden können -f
(die -N
Option müsste in diesem Szenario ebenfalls gelöscht werden).
Da Miller CSV-fähig ist, kommt es mit korrekt zitierten Feldern zurecht, die eingebettete Kommas, Anführungszeichen und Zeilenumbrüche enthalten.
Antwort4
Versuchen Sie den folgenden Befehl, um Spalten mithilfe des Index zu löschen.
dropColumnCSV --index=0 --file=file.csv
Dies würde funktionieren, wenn die Spalten durch Kommas getrennt sind, wiesedInnerhalb der Funktion werden Befehle zum Entfernen von Zeichenfolgen verwendet.
dropColumnCSV() {
# argument check
while [ $# -gt 0 ]; do
case "$1" in
--index=*)
index="${1#*=}"
;;
--file=*)
file="${1#*=}"
;;
*)
printf "* Error: Invalid argument. *\n"
return
esac
shift
done
# file check
if [ ! -f $file ]; then
printf "* Error: $file not found.*\n"
return
fi
# sed remove command index zero
if [[ $index == 0 ]]; then
sed -i 's/\([^,]*\),\(.*\)/\2/' $file
# sed remove command index greater than zero
elif [[ $index > 0 ]]; then
pos_str=$(for i in {1..$(seq "$index")}; do echo -n '[^,]*',; done| sed 's/,$//') ;
sed -i 's/^\('$pos_str'\),[^,]*/\1/' $file
fi
}