Existe um feitiço de linha de comando para eliminar uma coluna em um arquivo CSV?

Existe um feitiço de linha de comando para eliminar uma coluna em um arquivo CSV?

Ter um arquivo com o seguinte conteúdo:

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

Procuro obter um arquivo igual ao original, mas sem uma enésima coluna como, para n = 2 (ou pode ser 3)

1111,2222,4444
aaaa,bbbb,dddd

ou, para n = 0 (ou pode ser 1)

2222,3333,4444
bbbb,cccc,dddd

Um arquivo real pode ter gigabytes e dezenas de milhares de colunas.

Como sempre nesses casos, suspeito que os mágicos da linha de comando possam oferecer uma solução elegante... :-)

No meu caso real, preciso eliminar as 2 primeiras colunas, o que pode ser feito eliminando a primeira coluna duas vezes em uma sequência, mas suponho que seria mais interessante generalizar um pouco.

Responder1

Acredito que isso seja específico para cortar dos coreutils GNU:

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

Normalmente você especifica os campos desejados via -f, mas adicionando --complement você inverte o significado, naturalmente. De 'corte de homem':

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

Uma advertência: se alguma das colunas contiver uma vírgula, será cortado, porque cut não é um analisador CSV da mesma forma que uma planilha. Muitos analisadores têm ideias diferentes sobre como lidar com vírgulas de escape em CSV. Para o caso simples de CSV, na linha de comando, cut ainda é a melhor opção.

Responder2

Se os dados forem simplesmente compostos de colunas separadas por vírgula:

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

Você também pode usar o awk, mas é um pouco estranho porque, embora seja fácil limpar um campo, remover o separador dá algum trabalho. Se você não tiver nenhum campo vazio, não é tão ruim:

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

Se você tiver um CSV real, onde vírgulas podem aparecer dentro dos campos, se citadas corretamente, você precisará de umbiblioteca CSV real.

Responder3

Usando uma ferramenta compatível com CSV para remover as duas primeiras colunas de um arquivo de entrada CSV sem cabeçalho:

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

A -xopção pela cutoperação emMoleiro( mlr) faz com que a operaçãoexcluiros campos nomeados (neste caso, os campos número 1 e 2). Se os dados CSV tivessem cabeçalhos, poderíamos usar campos nomeados com -f(a -Nopção também precisaria ser eliminada neste cenário).

Como Miller reconhece CSV, ele lida com campos devidamente citados contendo vírgulas, aspas e novas linhas incorporadas.

Responder4

Experimente o comando abaixo para eliminar colunas usando índice.

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

Isso funcionaria se as colunas fossem separadas por vírgula, comosedcomandos são usados ​​​​dentro da função para remover strings.

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
}

informação relacionada