我有非常多的非常大的文件。
每个文件都包含这样的行:
uuid1 (tab) data1 (vtab) data2 ... dataN
uuid2 (tab) data1' (vtab) data2' (vtab) data3' (vtab) ... dataN'
....
其中N对于每一行都是不同的。结果需要看起来像:
uuid1 (tab) data1
uuid1 (tab) data2
....
uuid1 (tab) dataN
uuid2 (tab) data1'
uuid2 (tab) data2'
uuid2 (tab) data3'
...
uuid2 (tab) dataN'
....
我有一个正则表达式来完成这项工作,取而代之的是:
^([abcdef0123456789]{8}-[abcdef0123456789]{4}-[abcdef0123456789]{4}-[abcdef0123456789]{4}-[abcdef0123456789]{12})\t(.+?)\x0B
使用:
\1\t\2\n\1\t
但它很慢,显然需要重复申请。
是否有更快的编程方式在所有文件中执行此操作?
工具箱中可用的工具:unix工具(sed,awk等),python,可能是perl。
不寻求宗教战争,只是务实的做法。
其他信息
这是我使用的完整脚本,基于Kristof的脚本,用于处理外循环:
#!/usr/bin/python
import os
import uuid
def processFile( in_filename ):
out_filename = os.path.splitext(in_filename)[0] + '.result.txt'
with open(in_filename) as f_in:
with open(out_filename, 'w') as f_out:
for line in f_in:
try:
# Retrieve the line and split into UUID and data
line_uuid, data = line.split('\t')
# Validate UUID
uuid.UUID(line_uuid)
except ValueError:
# Ignore this line
continue
# Write each individual piece of data to a separate line
for data_part in data.rstrip().split('\x0b'):
f_out.write(line_uuid + '\t' + data_part + '\n')
for i in os.listdir(os.getcwd()):
if i.endswith(".txt"):
print i
processFile( i )
continue
else:
continue
答案 0 :(得分:2)
您可以使用awk脚本:
<强> script.awk:强>
BEGIN { FS="[\t\v]" }
{ for(i=2 ; i <= NF; i++ ) printf("%s\t%s\n",$1,$i) }
像这样:awk -f script.awk yourfile
(我没有尝试使用大型数据集,我真的很感兴趣它与其他解决方案相比如何。)
答案 1 :(得分:1)
这是Python中的一个实现(在3.5中测试)。我还没有在一个大型数据集上试过这个,我会留下让你尝试一下。
import uuid
in_filename = 'test.txt'
out_filename = 'parsed.txt'
with open(in_filename) as f_in:
with open(out_filename, 'w') as f_out:
for line in f_in:
try:
# Retrieve the line and split into UUID and data
line_uuid, data = line.split('\t', maxsplit=1)
# Validate UUID
uuid.UUID(line_uuid)
except ValueError:
# Ignore this line
continue
# Write each individual piece of data to a separate line
for data_part in data.rstrip().split('\x0b'):
f_out.write(line_uuid + '\t' + data_part + '\n')
答案 2 :(得分:1)
这是一个awk脚本,也会检查uuid。
它会忽略没有有效uuid的行。
BEGIN { FS="\v"; OFS="\t" }
{
split($1,a,/\s+/);
if (match(a[1], /^[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}$/, m))
{
print a[1],a[2];
for (i=2;i<=NF;i++) print a[1],$i;
}
}
在小文件上测试格式:
uuid(普通标签)data1(垂直标签)data2 ...(垂直标签)dataN
如果您确定uuid已经有效,那么删除if
自然会加速它,因为正则表达式匹配需要一些时间。但是,文件系统的速度可能会成为一个更大的瓶颈。
$ awk -f unpivot_data.awk input.txt > result.txt
$ cat result.txt
abcd1234-ab12-ab12-ab12-abcdef123456 data1
abcd1234-ab12-ab12-ab12-abcdef123456 data2
说实话,我希望一旦你测试了不同的解决方案,就可以与我们分享这样一个巨大文件的处理速度/速度越来越快。