我有一个大文件,其中有一个示例,如下
A222, 00000, 555
A222, 00100, 555
A222, 00200, 555
A222, 00300, 555
A222, 00000, 555
A222, 00100, 555
A222, 00000, 555
A222, 00200, 555
这是一个具有订单标题(00000(和相关订单详细信息(00100、00200等(的示例文件。我想将每个文件拆分为大约40000行,这样每个文件都有订单标题和订单详细信息。
我使用GNUparallel
实现了40000行的拆分,但我无法实现拆分以满足确保订单标题及其相关订单详细信息都在一行中的条件,确保每个文件每个有大约40000行
对于上面的示例文件,如果我必须每个拆分大约5行,我会使用下面的
parallel --pipe -N5 'cat > sample_{#}.txt' <sample.txt
但那会给我
sample1.txt
A222, 00000, 555
A222, 00100, 555
A222, 00200, 555
A222, 00300, 555
A222, 00000, 555
sample2.txt
A222, 00100, 555
A222, 00000, 555
A222, 00200, 555
它将在第一个文件中有2nd Order标头,在第二个文件中则有其相关的订单详细信息。
所需的应该是
sample1.txt
A222, 00000, 555
A222, 00100, 555
A222, 00200, 555
A222, 00300, 555
sample2.txt
A222, 00000, 555
A222, 00100, 555
A222, 00000, 555
A222, 00200, 555
您可以尝试以下代码:
( export hdr=$(head -1 sample.txt); parallel --pipe -N4 '{ echo "$hdr"; cat; } > sample_{#}.txt' < <(tail -n +2 sample.txt) )
我们基本上保持标题行独立,并在剩下的行上运行拆分,同时在每个拆分文件中包含标题。
当每个订单头都有很多记录时,您可以考虑简单的
csplit -z sample.txt '/00000,/' '{*}'
这将为每个订单标题创建一个文件。它不考虑40K的需求,可能会产生很多文件,并且只有当您有有限数量(可能是40?(的不同订单头时,它才是一个可行的解决方案。
当您确实希望在一个文件中组合不同的标头时,请考虑
awk -v max=40000 '
function flush() {
if (last+nr>max || sample==0) {
outfile="sample_" sample++ ".txt";
last=0;
}
for (i=0;i<nr;i++) print a[i] >> outfile;
last+=nr;
nr=0;
}
BEGIN { sample=0 }
/00000,/ { flush(); }
{a[nr++]=$0}
END { flush() }
' sample.txt
单个记录:
cat file | parallel --pipe --recstart 'A222, 00000, 555' -n1 'echo Single record;cat'
多条记录(最多--block-size
(
cat file | parallel --pipe --recstart 'A222, 00000, 555' --block-size 100 'echo Multiple records;cat'
如果"A222"不保持不变:
cat file | parallel -k --pipe --regexp --recstart '[A-Z]d+, 00000' -N1 'echo Single record;cat'