¿Hay un hechizo de línea de comando para colocar una columna en un archivo CSV?

32

Tener un archivo de los siguientes contenidos:

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

Busco obtener un archivo igual al original pero que carece de una enésima columna como, para n = 2 (o puede ser 3)

1111,2222,4444
aaaa,bbbb,dddd

o, para n = 0 (o puede ser 1)

2222,3333,4444
bbbb,cccc,dddd

Un archivo real puede tener una longitud de gigabytes con decenas de miles de columnas.

Como siempre en tales casos, sospecho que los magos de la línea de comandos pueden ofrecer una solución elegante ... :-)

En mi caso real real, necesito soltar 2 primeras columnas, lo que se puede hacer soltando una primera columna dos veces en una secuencia, pero supongo que sería más interesante generalizar un poco.

Ivan
fuente
¿Se garantiza que los campos no contienen ,? (Es decir, ,solo se usa como separador de campo.)
un CVn
@ MichaelKjörling, sería bueno tener una solución más flexible, pero en mi caso, sí: el separador es ,y nunca ocurre dentro de un campo.
Ivan
En ese caso, la respuesta de Scott debería ser la correcta.
un CVn

Respuestas:

47

Creo que esto es específico para cortar de los coreutils de GNU:

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

Normalmente, especifica los campos que desea mediante -f, pero al agregar --complemento, revierte el significado, naturalmente. De 'hombre cortado':

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

Una advertencia: si alguna de las columnas contiene una coma, se cortará, porque cortar no es un analizador CSV de la misma manera que una hoja de cálculo. Muchos analizadores tienen ideas diferentes sobre cómo manejar las comas de escape en CSV. Para el caso simple de CSV, en la línea de comando, cortar sigue siendo el camino a seguir.

Scott McClung
fuente
44
Eso funciona bien siempre que sea un simple archivo CSV. Si alguna de las columnas es una cadena con una coma, se cutdescartará porque no es un analizador CSV. Si un campo CSV tiene un separador de campo en su valor, está entre comillas. Por cierto, sobre el tema cut, -ftoma rangos de campo. cut -f, -d3-generará el tercer campo activado, eliminando los dos primeros.
Alexios
2
Quieres decircut -d, -f3-
Inútil
@Alexios ese es un buen punto. Realmente nunca trato con CSV "real", solo el subconjunto simple. Editaré mi respuesta para reflejar eso.
Scott McClung
@ Inútil: Maldición, sí. Eso es lo que llamo mi 'dislexia cortada' golpeando de nuevo. suspiro . Scott: los archivos CSV son bestias difíciles. Demasiados subformatos diferentes, algunos de los cuales ni siquiera son C SV, pero de todos modos se los llama convencionalmente.
Alexios
Esto imprime el nuevo CSV en mi terminal: ¿cómo consigo que sobrescriba la entrada (o quizás escriba en un nuevo archivo, parece que OP estaba buscando)?
Max Ghenis
12

Si los datos se componen simplemente de columnas separadas por comas:

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

También puede usar awk, pero es un poco incómodo porque, aunque borrar un campo es fácil, quitar el separador requiere algo de trabajo. Si no tiene un campo vacío, no está tan mal:

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

Si tiene un CSV real, donde las comas pueden aparecer dentro de los campos si se citan correctamente, necesita una biblioteca CSV real .

Gilles 'SO- deja de ser malvado'
fuente