使用于两个以上的小文件求交,并进行拼接 原理将各个文件以单独的对象存储,而后以key看成对应对象中的key,而后按照某个文件进行逐个对象拼接便可python
#!/bin/env python
# filename: merge_data_by_dict.py
fid_a = open('a.txt')
fid_b = open('b.txt')
fid_c = open('c.txt','w')
lines_a = fid_a.readlines()
lines_b = fid_b.readlines()
lines_c = []
for i in range(0,len(lines_b)):
lines_a[i]= lines_a[i].strip('\n\r')
lines_c.append(lines_a[i]+lines_b[i])
fid_c.writelines(lines_c[i])
复制代码
假定文件格式:shell
- 惟一字符串 \t 字段值1-1
- 惟一字符串 \t 字段值2-1 \t 字段值2-2
- 考虑将两个文件中的数据,按照惟一字符串聚合后,按照文件前后顺序进行排列
- 处理文件中的原始数据,为数据增长一列数据,该列数据值表明所属文件,且为数字便可
- 同时输出两份文件内容,并将文件按照指定列排序(聚合key、文件索引均需放到对应的列中),而后按照内容进行排序
- 准备一个python程序,逐行读取数据,并用下一行数据与上一行数据进行对比,看是否key相同,相同则将两份数据merge,不一样则跳过或输出当前行信息
file_index=0
cat ${file_path} \
| awk -F'\t' \
-v index="${file_index}" \
'{ other_str = ""; for(i=2; i<=NF; i++) { other_str = other_str"\t"$i; } print $1"\t"index""other_str; }' > ${file_path}.${file_index}
复制代码
cat file.1 file.2 | sort -k1 -k2 > file.tmp
复制代码
#!/bin/env python
# filename: merge_data.py
import sys
last_list = []
def main():
""" 主执行函数 """
global last_list
file0_empty_data = ['0', '0', '0']
file1_empty_data = ['0', '0', '0', '0']
for line in sys.stdin:
line = line.strip()
if not line:
continue
llist = line.split('\t')
if len(llist) not in [3, 4]:
continue
if not last_list:
if llist[1] == '0':
last_list = llist
else:
ret_list = file0_empty_data + llist
print "%s" % '\t'.join(tuple(ret_list)
else:
if llist[1] == '0':
ret_list = last_list + file1_empty_data
print "%s" % '\t'.join(tuple(ret_list)
last_list = llist
else:
if llist[0] == last_list[0]:
ret_list = last_list + llist
print "%s" % '\t'.join(tuple(ret_list)
last_list = []
else:
ret_list = last_list + file1_empty_data
print "%s" % '\t'.join(tuple(ret_list)
if last_list:
ret_list = last_list + file1_empty_data
print "%s" % '\t'.join(tuple(ret_list)
last_list = llist
if __name__ == '__main__':
main()
复制代码
cat file.tmp | python merge_data.py
复制代码
- 针对数据文件较大,没法直接操做两个文件时,能够参考该种方式
- 将文件按照指定key,进行hash计算,而后按照多个文件的方式进行hash输出到每一个小文件中
- 而后每一个小文件按照上述两种方案之一进行操做便可
假定文件格式bash
- 惟一字符串 \t 字段值1-1
- 惟一字符串 \t 字段值2-1 \t 字段值2-2
#!/bin/bash
file_nums=100
file_index=0
# 拆文件为各个小文件
cat file.1 | awk -F'\t' \
-v file_pos="${file_index}" \
-v file_nums="${file_nums}" \
'{ file_index = $1 % file_nums; file_path = "file_data."file_index; print file_pos"\t"$0 >> file_path; }'
function merge_data() {
local file_path=$1
cat ${file_path} 2>/dev/null \
| sort -k2 -k1 \
| python merge_data.py
}
# 遍历小文件进行求交拼接操做
for(( i=0; i<=$file_nums; i++ ));do
tmp_file_path="file_data."$i
merge_data "${tmp_file_path}"
done
复制代码