Ich habe eine CSV-Datei (etwa 10.000 Zeilen, jede Zeile hat 300 Spalten), die auf einem LINUX-Server gespeichert ist. Ich möchte diese CSV-Datei in 500 CSV-Dateien mit jeweils 20 Datensätzen aufteilen. (Jede Datei hat denselben CSV-Header wie die Original-CSV-Datei.)
Gibt es einen Linux-Befehl, der diese Konvertierung unterstützt?
Antwort1
Der Vollständigkeit halber hier einige kleinere Verbesserungen:
- Sie können den Header speicherneinmalund viele Male wiederverwenden
- Sie können den Header in die geteilten Dateien einfügen,
sed
ohne temporäre Dateien zu verwenden.
So was:
header=$(head -n 1 file.csv)
tail -n +2 file.csv | split -l 20
for file in x??; do
sed -i -e 1i$'\\\n'"$header" "$file"
done
Es $'\\\n'
gibt ein NEWLINE-Zeichen, das mit einem Backslash maskiert ist. Der sed
Ausdruck bedeutet: $header
vor der 1. Zeile einfügen.
Antwort2
Das sollte reichenohneder CSV-Header:
tail -n +2 file.csv | split -l 20
Anschließend können Sie den Header zu jeder der Dateien hinzufügen:
for file in x*
do
(head -n 1 file.csv; cat "$file") > "$file".new
mv "$file".new "$file" # Stolen from @PawanMude's answer
done
Antwort3
Versuchen:
fn="infile" c=0
{
read header
split -a 3 -l 3 - "$fn"
for f in "$fn"???; do
c=$((c+1))
printf "%s\n" "$header" | cat - "$f" > "${f%???}-$c" && rm "$f"
done
} < $fn
Oder versuchen Sie es mit awk:
awk 'NR==1{h=$0; next} !((NR-2)%n){close(f); f=FILENAME "-" ++c; print h>f}{print>f}' n=3 infile
mehrzeilige Version:
awk '
NR==1 {
h=$0
next
}
!((NR-2)%n) {
close(f)
f=FILENAME "-" ++c
print h>f
}
{
print>f
}
' n=3 infile
Antwort4
Verwenden Sie GNU Parallel:
cat bigfile.csv | parallel -N20 --header : --pipe 'cat > {#}'
Wenn Sie für jeden Teil einen Befehl ausführen müssen, kann GNU Parallel Ihnen dabei ebenfalls helfen:
cat bigfile.csv | parallel -N20 --header : --pipe my_program_reading_from_stdin
cat bigfile.csv | parallel -N20 --header : --pipe --cat my_program_reading_from_a_file {}