Esiste un incantesimo da riga di comando per eliminare una colonna in un file CSV?


32

Avere un file con i seguenti contenuti:

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

Cerco di ottenere un file uguale all'originale ma privo di una n-esima colonna come, per n = 2 (o può essere 3)

1111,2222,4444
aaaa,bbbb,dddd

oppure, per n = 0 (o può essere 1)

2222,3333,4444
bbbb,cccc,dddd

Un file reale può essere lungo gigabyte con decine di migliaia di colonne.

Come sempre in questi casi, sospetto che i maghi della riga di comando possano offrire una soluzione elegante ... :-)

Nel mio caso reale ho bisogno di eliminare 2 prime colonne, cosa che può essere fatta rilasciando una prima colonna due volte in una sequenza, ma suppongo che sarebbe più interessante generalizzare un po '.


I campi sono garantiti non contenere ,? (Cioè, ,è sempre e solo usato come un separatore di campo.)
un CVn

@ MichaelKjörling, sarebbe bello avere una soluzione più flessibile, ma nel mio caso - sì: il separatore è ,e non si verifica mai all'interno di un campo.
Ivan

In tal caso, la risposta di Scott dovrebbe essere la cosa giusta.
un CVn del

Risposte:


47

Credo che questo sia specifico per tagliare dai coreutils GNU:

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

Normalmente si specificano i campi che si desidera tramite -f, ma aggiungendo --complement si inverte il significato, naturalmente. Da 'man cut':

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

Un avvertimento: se una delle colonne contiene una virgola, verrà eliminata, poiché cut non è un parser CSV nello stesso modo di un foglio di calcolo. Molti parser hanno idee diverse su come gestire le virgole di escape in CSV. Per il semplice caso CSV, sulla riga di comando, tagliare è ancora la strada da percorrere.


4
Funziona bene purché sia ​​un semplice file CSV. Se una delle colonne è una stringa con una virgola, verrà cuteliminata perché non è un parser CSV. Se un campo CSV ha un separatore di campo nel suo valore, è racchiuso tra virgolette. A proposito, in materia di cut, -fprende le gamme di campo. cut -f, -d3-genererà il terzo campo, rimuovendo i primi due.
Alexios

2
Intendicut -d, -f3-
Inutile

@Alexios è un buon punto. Non ho mai veramente a che fare con CSV "reali", solo il semplice sottoinsieme. Modificherò la mia risposta per riflettere ciò.
Scott McClung,

@Useless: Accidenti, sì. Questo è ciò che chiamo ancora una volta la mia "dislessia tagliata". sospiro . Scott: I file CSV sono bestie difficili. Troppi sub-formati diversi, alcuni dei quali non sono nemmeno in C SV, ma sono comunque convenzionalmente chiamati così.
Alessio

Questo stampa il nuovo CSV sul mio terminale - come posso farlo sovrascrivere l'input (o forse scrivere su un nuovo file, sembra che OP stesse cercando uno dei due)?
Max Ghenis,

12

Se i dati sono semplicemente costituiti da colonne separate da virgola:

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

Puoi anche usare awk, ma è un po 'imbarazzante perché mentre si cancella un campo è facile, rimuovere il separatore richiede un po' di lavoro. Se non hai un campo vuoto, non è male:

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

Se hai un CSV effettivo, in cui le virgole possono apparire all'interno dei campi se correttamente citate, hai bisogno di una vera libreria CSV .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.