我有一个 csv 文件,需要将其分解为较小的文件。 split -l 20000 test.csv 没有问题我的问题是该文件包含不同的标题。想要分割,比如每 +-1000 行,但它需要在 pay 标头之后分割,并且新文件需要以 cust 标头开始。
客户标头,xxx,xxxxxx,xxxxxx txn 标头,xxxx,xxx,,xxxx,xxxxx,,xxx 详细标题,xxxx,xxxx,xxxxxx,xxxx,xxxx 详细标题,xxxxxxxx,xxxxxxxxxx,xxx,, 付款标题,,,,,xxxx,xxxxx 客户标头,xxx,xxxxxx,xxxxxx txn 标头,xxxx,xxx,,xxxx,xxxxx,,xxx 详细标题,xxxx,xxxx,xxxxxx,xxxx,xxxx 付款标题,,,,,xxxx,xxxxx 客户标头,xxx,xxxxxx,xxxxxx txn 标头,xxxx,xxx,,xxxx,xxxxx,,xxx 详细标题,xxxx,xxxx,xxxxxx,xxxx,xxxx 付款标题,,,,,xxxx,xxxxx
答案1
你可以这样做awk
:
awk -vfilename=output -vcut=1000 '
BEGIN { nl=0; nf=1; f=filename "." nf;}
++nl >= cut && /^cust header,/ {
close(f); nl=0; f=filename "." ++nf}
{print > f}' < file
它会记录所看到的行数,如果计数大于cut
(此处为 1000)并且当前行以cust header,
.输出文件名为output.1
, output.2
, ...(filename
变量)
答案2
ilkkachu 的解决方案很巧妙,使用单个可执行文件,并且可能是正确的答案。然而,我一直无法理解awk
.如果 ilkkachu 没有先回答,我可能会选择csplit
。 csplit
将根据分割文本文件上下文线(好吧,正则表达式)。然后,您可以获取该输出并使用split
您已知的实用程序进一步拆分文件:
$ csplit --prefix="MySplit." test.csv '/^cust header,/' '{*}'
0
174
134
134
这些是每个块的字节数(在本例中我们忽略)。现在,迭代每个MySplit
块并进一步拆分为您的 20k 要求:
$ for i in MySplit.0*; do
split --additional-suffix=".$i" -l 20000 "$i"
done
例如,使用-l 2
而不是 20k,给定样本的最终输出将是(按扩展名排序):
$ ls -lhXB
total 44K
-rw-r--r-- 1 hunteke hunteke 0 Jun 15 13:31 MySplit.00
-rw-r--r-- 1 hunteke hunteke 174 Jun 15 13:31 MySplit.01
-rw-r--r-- 1 hunteke hunteke 67 Jun 15 13:27 xaa.MySplit.01
-rw-r--r-- 1 hunteke hunteke 81 Jun 15 13:27 xab.MySplit.01
-rw-r--r-- 1 hunteke hunteke 26 Jun 15 13:27 xac.MySplit.01
-rw-r--r-- 1 hunteke hunteke 134 Jun 15 13:31 MySplit.02
-rw-r--r-- 1 hunteke hunteke 67 Jun 15 13:27 xaa.MySplit.02
-rw-r--r-- 1 hunteke hunteke 67 Jun 15 13:27 xab.MySplit.02
-rw-r--r-- 1 hunteke hunteke 134 Jun 15 13:31 MySplit.03
-rw-r--r-- 1 hunteke hunteke 67 Jun 15 13:27 xaa.MySplit.03
-rw-r--r-- 1 hunteke hunteke 67 Jun 15 13:27 xab.MySplit.03
-rw-r--r-- 2 hunteke hunteke 442 Jun 15 13:06 test.csv