如何根據指定的行數拆分 CSV 檔案?

如何根據指定的行數拆分 CSV 檔案?

我有 CSV 檔案(大約 10,000 行;每行有 300 列)儲存在 LINUX 伺服器上。我想將此 CSV 文件分成 500 個 CSV 文件,每個文件有 20 筆記錄。 (每個都具有與原始 CSV 中相同的 CSV 標頭)

有沒有什麼linux指令可以幫助這種轉換?

答案1

為了完整起見,這裡有一些小的改進:

  • 您可以儲存標題一次並重複使用多次
  • sed您可以使用不使用臨時檔案的方式將標頭插入到分割檔案中

像這樣:

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

$'\\\n'一個用反斜線轉義的 NEWLINE 字元。表達式sed的意思是:$header在第一行之前插入。

答案2

這應該可以做到沒有CSV 標頭:

tail -n +2 file.csv | split -l 20

然後,您可以將標頭新增到每個文件中:

for file in x*
do
    (head -n 1 file.csv; cat "$file") > "$file".new
    mv "$file".new "$file" # Stolen from @PawanMude's answer
done

答案3

嘗試:

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

或嘗試使用 awk:

awk 'NR==1{h=$0; next} !((NR-2)%n){close(f); f=FILENAME "-" ++c; print h>f}{print>f}' n=3 infile

多行版本:

awk '
  NR==1 {
    h=$0
    next
  }
  !((NR-2)%n) {
    close(f)
    f=FILENAME "-" ++c
    print h>f
  }
  {
    print>f
  }
' n=3 infile

答案4

使用 GNU 並行:

cat bigfile.csv | parallel -N20 --header : --pipe 'cat > {#}'

如果您需要在每個部分上執行命令,那麼 GNU Parallel 也可以幫助您做到這一點:

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 {}

相關內容