最近由於業務系統新需求的需要,我們平臺需要將供應商G提供一類數據轉換格式後提供給客戶K。比較頭疼是供應商G提供的數據都是在Windows下使用Excel存儲的,而客戶K先前與我們相關對接人員商定的數據類型必須使用utf-8的txt文件,並且由於客戶K程式處理的需要,並附帶生成一個與該數據文件匹配的校 ...
最近由於業務系統新需求的需要,我們平臺需要將供應商G提供一類數據轉換格式後提供給客戶K。比較頭疼是供應商G提供的數據都是在Windows下使用Excel存儲的,而客戶K先前與我們相關對接人員商定的數據類型必須使用utf-8的txt文件,並且由於客戶K程式處理的需要,並附帶生成一個與該數據文件匹配的校驗文件數據傳輸的結束標誌。
主要操作步驟如下:
1,首先得先把.xlsx的尾碼改為.csv的尾碼另存,這樣就可以在Linux中打開了;
2,由於Windows下編碼格式基本都是gbk的,所以需要進行轉碼為utf-8的才能顯示正常。
可以使用 iconv -fgbk -tutf8 -c -o to_file from_file 進行轉碼,轉碼後文件大致顯示如下:
賬號,銀行,姓名,身份證號,手機號,登錄郵箱,嫌疑欺詐賬戶使用設備,請求類型,,,是否被多家公安機關查詢 000167342xxx,深圳農商,深圳市XX倉儲服務有限公司,,,,,止付,凍結,明細查詢,是 000195557xxx,深圳農商,深圳市XXX鞋材有限公司,,,,,止付,凍結,明細查詢,是 000251484xxx,深圳農商,深圳市XXX電子有限公司,,,,,止付,凍結,明細查詢,是
實際上只有9列數據,第8、9、10是合併單元格的。
3,客戶K要求9列數據使用 “|” 進行分割。
由上面轉碼後文件內容可知,目前以 “,” 進行分割有11列數據,第8、9、10三列繼續使用 “,” 進行分割,其他使用 “|” 進行分割。就我當前知識範圍來講,可以使用兩種
方式,一種是使用Python,不過腳本實現起來比較複雜。一種使用AWK的流文本處理,命令簡單,建議優先採用。但是也可以使用shell利用for迴圈進行拼接,但是這種需要消耗大量的系統資源,並且出奇的慢,不建議使用。供應商G提供文件大概有12W行數據,使用這種方式需要近20分鐘才能完成。下麵分別介紹兩種方式:
3.1 Python腳本如下:
import sys def readfile(rfilename,wfilename): wfile=open(wfilename,'a+') #wfile.write('賬號|銀行|姓名|身份證號|手機號|登錄郵箱|嫌疑欺詐賬戶使用設備|請求類型|是否被多家公安機關查詢\n') #上一行是文件的title,如果不使用這樣的方式,就是用下麵lines從0,也即是從第一行開始處理 with open(rfilename, 'r') as fr: lines=fr.readlines() for line in lines[0:]: llist=[] if len(line)>1: words=line.split(',') if (words[0]!=''): llist.append(words[0]+'|') llist.append(words[1]+'|') llist.append(words[2]+'|') llist.append(words[3]+'|') llist.append(words[4]+'|') llist.append(words[5]+'|') llist.append(words[6]+'|') llist.append(words[7]+',') llist.append(words[8]+',') llist.append(words[9]+'|') llist.append(words[10]) wstr=''.join(llist) #這裡需要指定新文件列之間的分隔符為空,否則每個欄位間會有多個分隔符 wfile.write(wstr+'\r') #這裡的行與行之間使用換行符 \r ,而不是使用回車 \n,如果使用回車則新文件中會生成大量空行 wfile.close() if __name__ == '__main__': inpath=sys.argv[1] outpath=sys.argv[2] #指定輸入文件的路徑和名稱 rfilename=inpath+'1111.csv' #指定輸出文件路徑和名稱 wfilename=outpath+'3333.csv' readfile(rfilename,wfilename) #執行 [root@A opt] python $python_file $inpath $outpath
速度很快,1秒鐘左右12W行就執行完了。
3.2 AWK
awk -F, '{print $1"|",$2"|",$3"|",$4"|",$5"|",$6"|",$7"|",$8",",$9",",$10"|",$11}' 1111.csv | sed 's/ //g' >>ttt2.csv
就這麼簡單的一個命令,12W行秒完成。
3.3 shell的方式,相比於AWK流文本處理和Python腳本,使用shell處理,至少我想出來的這個方法的確是太蠢了。
#執行前, 我先把,改成| for line in `cat 3333.txt` do echo "`echo "$line" | awk -F "|" 'BEGIN{OFS="|"} {print $1,$2,$3,$4,$5,$6,$7}'`|`echo "$line" | awk -F"|" 'BEGIN{OFS=","} {print $8,$9,$10}'`|`echo "$line" | awk -F "|" 'BEGIN{OFS="|"} {print $11}'`" >> 4444.txt done #當然情況允許的話, 還可以使用並行 for line in `cat 3333.txt` do { echo "`echo "$line" | awk -F "|" 'BEGIN{OFS="|"} {print $1,$2,$3,$4,$5,$6,$7}'`|`echo "$line" | awk -F"|" 'BEGIN{OFS=","} {print $8,$9,$10}'`|`echo "$line" | awk -F "|" 'BEGIN{OFS="|"} {print $11}'`" >> 4444.txt }& done
經過測試發現,並行與否好像沒有多大的差別,只是稍微快了那麼一丟丟,也需要近20分鐘才能完成12W行的拼接。
以上三種方法處理後數據就是下麵的了:
賬號|銀行|姓名|身份證號|手機號|登錄郵箱|嫌疑欺詐賬戶使用設備|請求類型|是否被多家公安機關查詢 000167342xxx|深圳農商|深圳市XX倉儲服務有限公司|||||止付,凍結,明細查詢|是 000195557xxx|深圳農商|深圳市XXX鞋材有限公司|||||止付,凍結,明細查詢|是 000251484xxx|深圳農商|深圳市XXX電子有限公司|||||止付,凍結,明細查詢|是 001980099990xxx|農業銀行|未知|||||,,明細查詢|是
4,生成校驗文件就很簡單了,可以使用MD5的,16位的加密;也可以使用hash的,hash預設是SHA-1的,20位的加密,也有SHA-224、SHA-256、SHA-384
#命令示例 [root@A opt]# md5sum 2222.csv d6b37d6921b0153079ef6bb976872f01 2222.csv [root@A opt]# sha1sum 2222.csv c9e780381f756308362d44172e06e46ee8758ecf 2222.csv [root@A opt]# sha224sum 2222.csv 1f79435e1f5eefc91b1fabf66df1a25391478e0fa137a526e6bdf66e 2222.csv [root@A opt]# sha256sum 2222.csv bf9e8b0b25807e9b31026a56d8dc4040dd4c90e7a468b1a4d91cc3b6866dbb13 2222.csv #生成校驗文件 [root@A opt]# md5sum 2222.csv >2222_md5.txt [root@A opt]# sha1sum 2222.csv >2222_sha1.txt #校驗文件完整性 [root@A opt]# md5sum -c 2222_md5.txt 2222.csv: OK [root@A opt]# sha1sum -c 2222_sha1.txt 2222.csv: OK
更多關於校驗文件生成的解讀詳見:https://www.jb51.net/LINUXjishu/156064.html