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

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

Contando con un fichero del siguiente contenido:

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

Busco obtener un archivo igual al original pero al que le falta 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 gigabytes de longitud y decenas de miles de columnas.

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

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

Respuesta1

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

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

Normalmente especificas los campos que deseas mediante -f, pero al agregar --complement inviertes 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 cut no es un analizador CSV de la misma manera que lo es 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.

Respuesta2

Si los datos están formados simplemente por columnas separadas por comas:

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

También puedes usar awk, pero es un poco incómodo porque, si bien borrar un campo es fácil, eliminar el separador requiere algo de trabajo. Si no tienes ningún campo vacío, no está tan mal:

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

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

Respuesta3

Usando una herramienta compatible con CSV para eliminar las dos primeras columnas de un archivo de entrada CSV sin encabezado:

$ cat file
1111,2222,3333,4444
aaaa,bbbb,cccc,dddd
$ mlr --csv -N cut -x -f 1,2 file
3333,4444
cccc,dddd

La -xopción a la cutoperación enMolinero( mlr) hace que la operaciónexcluirlos campos nombrados (en este caso, los campos número 1 y 2). Si los datos CSV hubieran tenido encabezados, habríamos podido usar campos con nombre -f(la -Nopción también debería eliminarse en este escenario).

Dado que Miller admite CSV, puede manejar campos entre comillas correctamente que contienen comas, comillas y nuevas líneas incrustadas.

Respuesta4

Pruebe el siguiente comando para eliminar columnas usando el índice.

dropColumnCSV --index=0 --file=file.csv

Esto funcionaría si las columnas están separadas por comas, comosedLos comandos se utilizan dentro de la función para eliminar cadenas.

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
}

información relacionada