Este one-liner dividirá el csv grande en partes de 999 registros, conservando la fila del encabezado en la parte superior de cada uno (por lo que 999 registros + 1 encabezado =1000 filas)
cat bigFile.csv | parallel --header : --pipe -N999 'cat >file_{#}.csv'
Basado en la respuesta de Ole Tange.
Consulte los comentarios para obtener algunos consejos sobre la instalación en paralelo
Esta es la de robhruska el guión se limpió un poco:
tail -n +2 file.txt | split -l 4 - split_
for file in split_*
do
head -n 1 file.txt > tmp_file
cat "$file" >> tmp_file
mv -f tmp_file "$file"
done
Eliminé wc
, cut
, ls
y echo
en los lugares donde son innecesarios. Cambié algunos de los nombres de archivo para hacerlos un poco más significativos. Lo dividí en varias líneas solo para que sea más fácil de leer.
Si quieres ponerte elegante, puedes usar mktemp
o tempfile
para crear un nombre de archivo temporal en lugar de usar uno codificado.
Editar
Usando GNU split
es posible hacer esto:
split_filter () { { head -n 1 file.txt; cat; } > "$FILE"; }; export -f split_filter; tail -n +2 file.txt | split --lines=4 --filter=split_filter - split_
Desglosado para facilitar la lectura:
split_filter () { { head -n 1 file.txt; cat; } > "$FILE"; }
export -f split_filter
tail -n +2 file.txt | split --lines=4 --filter=split_filter - split_
Cuando --filter
se especifica, split
ejecuta el comando (una función en este caso, que debe exportarse) para cada archivo de salida y establece la variable FILE
, en el entorno del comando, al nombre de archivo.
Una secuencia de comandos o función de filtro podría hacer cualquier manipulación que quisiera en los contenidos de salida o incluso en el nombre del archivo. Un ejemplo de esto último podría ser la salida a un nombre de archivo fijo en un directorio variable:> "$FILE/data.dat"
por ejemplo.
Podría usar la nueva funcionalidad --filter en GNU coreutils split>=8.13 (2011):
tail -n +2 FILE.in | split -l 50 - --filter='sh -c "{ head -n1 FILE.in; cat; } > $FILE"'