如何按照指定的行数拆分CSV文件?


83

我已经将CSV文件(大约10,000行;每行具有300列)存储在LINUX服务器上。我想将此CSV文件分解为500个CSV文件,每个文件20条记录。(每个具有与原始CSV中相同的CSV标头)

有什么linux命令可以帮助这种转换吗?


1
确实确实可以,但是第一个文件的标头将被复制,从而为第一个csv文件提供2个标头。
里克曼


Answers:


79

使其成为一个函数。您现在可以打电话splitCsv <Filename> [chunkSize]

splitCsv() {
    HEADER=$(head -1 $1)
    if [ -n "$2" ]; then
        CHUNK=$2
    else 
        CHUNK=1000
    fi
    tail -n +2 $1 | split -l $CHUNK - $1_split_
    for i in $1_split_*; do
        sed -i -e "1i$HEADER" "$i"
    done
}

发现于:http : //edmondscommerce.github.io/linux/linux-split-file-eg-csv-and-keep-header-row.html


1
您能解释一下它的工作方式吗?我检查了原始帖子,但也没有任何解释,甚至也没有发表评论的选项。
shashi009 2013年

6
如果CSV中的单元格包含换行符怎么办?
的OndrejHlaváček

这是什么样的换行符?对于UTF-8,它仍然对我有用,不确定是否有帮助。
owyongsk

3
@ shashi009:假定原始文件名为file.txt。1:跳过第一行,然后将文件的其余部分通过管道传输到中split,然后将其分割成每20行长的带有前缀split_2的新文件:遍历新的split_ *文件,将每个名称file一次存储到变量中3:每个... 4:将原始文件的第一行(列标题)写到tmp_file 5:将20行拆分文件追加到tmp_file 6:用new覆盖旧的split_ *文件tmp_file,因此保留列标题
大卫

1
通过头文件头echo -e "$HEADER\n$(cat $i)" > $i不必要地不正确。我将其替换为sed -i -e "1i$HEADER" "$i"
菲利普·莫尔斯

146

使用Linux split命令:

split -l 20 file.txt new    

将文件“ file.txt”拆分为以“ new”开头的文件,每个文件包含20行文本。

man split在Unix提示符下键入以获取更多信息。但是,您必须首先从file.txt中删除标题(tail例如,使用命令),然后再将其重新添加到每个拆分文件中。


如何跳过file.txt第一行(标题)?
forkfork

用于wc -l获取行数,然后将该值减去1(假设wc -l为50),然后运行tail -n 49(在此示例中)以获取除标题行以外的所有内容。请注意,该wc -l字符计数<newline>,因此如果最后一行未以换行符结尾,则行数将减少1。
卢卡斯·罗伯茨

4
@lucas, tail -n +2 将打印除第一行外的所有行。
詹姆斯·金

@ JamesKing,+ 1,谢谢!我应该更仔细地阅读文档:)
卢卡斯·罗伯茨

6
只需添加“ .csv”到新文件中即可--additional-suffix=.csv
Cocuba

21

这应该工作!

file_name=您要分割的文件名。
10000=每个拆分文件将包含的行数
file_part_=拆分文件名的前缀(file_part_0,file_part_1,file_part_2..etc继续存在)

分割-d -l 10000 file_name.csv file_part_


这绝对好用!有没有一种方法可以限制我创建的10000行文件的数量。假设我只希望将前200,000行分为10k行csv文件,而忽略其余的行。
Pronomita Dey

1
@Pronomitahead -200000 file.csv | split -l 10000 - new_
boloyao

2
我有一个13 Gb CSV文件,其中损坏的行大约在〜69 000 000行。它阻止了导入bigquery。这使我可以递归拆分它,直到可以隔离行并对其进行修复。在不关闭服务器或锁定服务器的情况下,没有其他解决方案能够有效地处理大文件。花费了大约2分钟的时间将文件拆分为5000000行块。谢谢!
LP Papillon,

13

这应该为您完成-您的所有文件最终都将称为Part1-Part500。

#!/bin/bash
FILENAME=10000.csv
HDR=$(head -1 $FILENAME)   # Pick up CSV header line to apply to each file
split -l 20 $FILENAME xyz  # Split the file into chunks of 20 lines each
n=1
for f in xyz*              # Go through all newly created chunks
do
   echo $HDR > Part${n}    # Write out header to new file called "Part(n)"
   cat $f >> Part${n}      # Add in the 20 lines from the "split" command
   rm $f                   # Remove temporary file
   ((n++))                 # Increment name of output part
done

这样就创建了文件,但是制表符(我的意思是\ t)被替换为空格,而我的CSV文件使用\ t作为分隔符
AmineG 2015年

可以通过对数字进行填充来略微改善此状况,以便自动连续显示文件。通过用$(printf“%05d \ n” $ n)代替$ {n}
Phineas Dashevsky

4
标题行在第一个文件中重复。
JuhaPalomäki17年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.