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 -x
opção pela cut
operaçã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 -N
opçã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
}