Este comando GNU awk faz o truque:
awk -F ',' 'NR==1{h=$0; next};!seen[$1]++{f=$1".csv"; print h > f};{f=$1".csv"; print >> f; close(f)}' input.csv
Advertência: Isso não funcionará se houver vírgulas com escape no primeiro campo. Vírgulas em outros campos devem funcionar bem.
Explicação:
-
-F ','
(separador de campo) garante que$1
etc. se refiram às colunas CSV, em vez de valores separados por espaços. -
NR==1{h=$0; next}
trata a primeira linha especialmente (NR==1
), armazenando a linha de cabeçalho completa em uma variávelh
(h=$0
) e pulando a linha (next
). -
!seen[$1]++{f=$1".csv"; print h > f}
trata a primeira ocorrência de qualquer$1
especialmente (!seen[$1]
) armazenando$1
seguido de.csv
em uma variável de nome de arquivof
e salvando o cabeçalho nesse arquivo (print h > f
). -
{f=$1".csv"; print >> f; close(f)}
adiciona a linha atual ao arquivo (print >> f
) e fecha o descritor de arquivo (close(f)
) para evitar mantê-lo assim que o processamento de todas as linhas com um ID específico for concluído.
Bônus: se você substituir $1
por outro campo, ele deverá fazer o que você espera: criar um arquivo por valor único nessa coluna com as linhas que contêm esse valor na coluna especificada.