拆分文件而不分隔以 Unix 中的相似值开头的行
Split file without separating rows beginning with like values in Unix
我有一个经过排序的 .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 GB,包含超过 1 亿行。我想把它分成大约 100K 行或 ~6MB 的文件。我可以使用文件大小或行号进行拆分。
我知道可以用"sort"拆分,如:
split -a 5 -d -1 2
在这里,这将给我四个文件,并且在大多数情况下,第一列中的类似值将拆分为多个文件。
我想我可能需要 awk,但是,即使阅读了手册,我也不确定如何进行。
感谢帮助!谢谢!
一个awk
脚本:
BEGIN { FS = "," }
!name { name = sprintf("%06d-%s.txt", NR, ) }
count >= 2 && prev != {
close(name)
name = sprintf("%06d-%s.txt", NR, )
count = 0
}
{
print >name
prev =
++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)
在完成此操作的两个位置设置输出文件名。
使用 csplit(如果可用)
根据给定的数据
csplit -s infile %^A% /^C/ %^C% /^D/ /^Z/ {*}
我有一个经过排序的 .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 GB,包含超过 1 亿行。我想把它分成大约 100K 行或 ~6MB 的文件。我可以使用文件大小或行号进行拆分。
我知道可以用"sort"拆分,如:
split -a 5 -d -1 2
在这里,这将给我四个文件,并且在大多数情况下,第一列中的类似值将拆分为多个文件。
我想我可能需要 awk,但是,即使阅读了手册,我也不确定如何进行。
感谢帮助!谢谢!
一个awk
脚本:
BEGIN { FS = "," }
!name { name = sprintf("%06d-%s.txt", NR, ) }
count >= 2 && prev != {
close(name)
name = sprintf("%06d-%s.txt", NR, )
count = 0
}
{
print >name
prev =
++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)
在完成此操作的两个位置设置输出文件名。
使用 csplit(如果可用)
根据给定的数据
csplit -s infile %^A% /^C/ %^C% /^D/ /^Z/ {*}