Questo one-liner dividerà il grande csv in pezzi di 999 record, preservando la riga di intestazione nella parte superiore di ciascuno (quindi 999 record + 1 intestazione =1000 righe)
cat bigFile.csv | parallel --header : --pipe -N999 'cat >file_{#}.csv'
Basato sulla risposta di Ole Tange.
Vedere i commenti per alcuni suggerimenti sull'installazione parallela
Questo è di robhruska script è stato ripulito un po':
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
Ho rimosso wc
, cut
, ls
e echo
nei luoghi in cui non sono necessari. Ho cambiato alcuni nomi di file per renderli un po' più significativi. L'ho suddiviso su più righe solo per facilitarne la lettura.
Se vuoi essere fantasioso, puoi usare mktemp
o tempfile
per creare un nome file temporaneo invece di usarne uno hardcoded.
Modifica
Utilizzo di GNU split
è possibile farlo:
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_
Scomposto per leggibilità:
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_
Quando --filter
è specificato, split
esegue il comando (una funzione in questo caso, che deve essere esportata) per ogni file di output e imposta la variabile FILE
, nell'ambiente del comando, al nome del file.
Uno script o una funzione di filtro potrebbe eseguire qualsiasi manipolazione desiderata sul contenuto dell'output o persino sul nome del file. Un esempio di quest'ultimo potrebbe essere l'output con un nome file fisso in una directory variabile:> "$FILE/data.dat"
Per esempio.
Puoi usare la nuova funzionalità --filter in GNU coreutils split>=8.13 (2011):
tail -n +2 FILE.in | split -l 50 - --filter='sh -c "{ head -n1 FILE.in; cat; } > $FILE"'