拆分文件而不分隔以Unix

时间:2018-05-14 19:54:23

标签: unix awk split gawk

我有一个排序的.csv文件,如下所示:

AABB1122,ABC,BLAH,4
AABB1122,ACD,WHATEVER,1
AABB1122,AGT,CAT,4
CCDD4444,AYT,DOG,4
CCDD4444,ACG,MUMMY,8
CCEE4444,AOP,RUN,5
DDFF9900,TUI,SAT,33
DDFF9900,WWW,INDOOR,5

我想将文件拆分为每个大约两行的较小文件,但我不希望第一列中具有相同值的行分开。

在这里,我最终会得到三个文件:

X00000:

AABB1122,ABC,BLAH,4
AABB1122,ACD,WHATEVER,1
AABB1122,AGT,CAT,4

X00001:

CCDD4444,AYT,DOG,4
CCDD4444,ACG,MUMMY,8

X00002:

CCEE4444,AOP,RUN,5
DDFF9900,TUI,SAT,33
DDFF9900,WWW,INDOOR,5 

我的实际数据大小约为7演出,包含超过1亿行。我想把它分成每个约100K行或~6MB的文件。我可以使用文件大小或行号进行拆分。

我知道我可以使用“排序”来分割,例如:

split -a 5 -d -1 2

在这里,这将给我四个文件,并且在大多数情况下,第一列中的值将被分割为文件。

我想我可能需要awk,但是,即使在阅读完手册之后,我也不确定如何继续。

感谢帮助!谢谢!

2 个答案:

答案 0 :(得分:2)

awk脚本:

BEGIN   { FS = ","  }
!name   { name = sprintf("%06d-%s.txt", NR, $1) }

count >= 2 && prev != $1  {
    close(name)
    name = sprintf("%06d-%s.txt", NR, $1)
    count = 0
}

{
    print >name
    prev = $1
    ++count
}

在给定数据上运行此操作将创建三个文件:

$ awk -f script.awk file.csv

$ cat 000001-AABB1122.txt
AABB1122,ABC,BLAH,4
AABB1122,ACD,WHATEVER,1
AABB1122,AGT,CAT,4

$ cat 000004-CCDD4444.txt
CCDD4444,AYT,DOG,4
CCDD4444,ACG,MUMMY,8

$ cat 000006-CCEE4444.txt
CCEE4444,AOP,RUN,5
DDFF9900,TUI,SAT,33
DDFF9900,WWW,INDOOR,5

我随意选择使用原始文件中的第一行所用的行号,以及该行的第一个字段数据作为文件名。

脚本计算打印到当前输出文件的行数,如果该数字大于或等于2,并且第一个字段的值与前一行的值不同,则字段,关闭当前输出文件,构造新的输出名称,并重置计数。

最后一个块只是打印到当前文件名,记住prev变量中的第一个字段,并递增计数。

BEGIN块初始化字段分隔符(在读取第一行之前),!name块设置初始输出文件名(读取第一行时)。

要准确获取问题中的文件名,请使用

name = sprintf("x%05d", ++n)

在两个地方设置输出文件名。

答案 1 :(得分:0)

使用csplit(如果可用)

使用给定数据

goto [case label]