文件求交拼接方式

python 方式求交拼接

使用於兩個以上的小文件求交,並進行拼接 原理將各個文件以單獨的對象存儲,而後以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 + python 方式求交拼接(方案一)

假定文件格式:shell

  1. 惟一字符串 \t 字段值1-1
  2. 惟一字符串 \t 字段值2-1 \t 字段值2-2

假定文件不是特別大,且本地能夠運行,文件行數假定百萬級別

  1. 考慮將兩個文件中的數據,按照惟一字符串聚合後,按照文件前後順序進行排列
  2. 處理文件中的原始數據,爲數據增長一列數據,該列數據值表明所屬文件,且爲數字便可
  3. 同時輸出兩份文件內容,並將文件按照指定列排序(聚合key、文件索引均需放到對應的列中),而後按照內容進行排序
  4. 準備一個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
複製代碼

shell + python 方式求交拼接(方案二)

  1. 針對數據文件較大,沒法直接操做兩個文件時,能夠參考該種方式
  2. 將文件按照指定key,進行hash計算,而後按照多個文件的方式進行hash輸出到每一個小文件中
  3. 而後每一個小文件按照上述兩種方案之一進行操做便可

假定文件格式bash

  1. 惟一字符串 \t 字段值1-1
  2. 惟一字符串 \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
複製代碼
相關文章
相關標籤/搜索