![如何根据指定的行数拆分 CSV 文件?](https://linux22.com/image/1390616/%E5%A6%82%E4%BD%95%E6%A0%B9%E6%8D%AE%E6%8C%87%E5%AE%9A%E7%9A%84%E8%A1%8C%E6%95%B0%E6%8B%86%E5%88%86%20CSV%20%E6%96%87%E4%BB%B6%EF%BC%9F.png)
我在 LINUX 服务器上存储了一个 CSV 文件(大约 10,000 行;每行有 300 列)。我想将此 CSV 文件拆分为 500 个 CSV 文件,每个文件有 20 条记录。(每个 CSV 文件的 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 Parallel:
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 {}