資料檔案合併與拆分
在資料處理業務中,經常要把檔案結構相同或近似相同的資料檔案合併成一個檔案,或者將一個比較大的資料檔案拆分成小的資料檔案。本文將介紹文字檔案和 Excel 檔案合併及拆分會遇到的幾種情況,並提供用 esProc SPL 編寫的程式碼示例。esProc 是專業的資料計算引擎,SPL 中有完善的檔案匯入、匯出及目錄操作函式,非常適合做資料檔案的合併及拆分工作。
一、 檔案合併
1. 同構文字檔案合併
在某個檔案目錄下有多個文字檔案,這些檔案表頭和列結構完全相同,只是資料行數和資料內容不同,需要將這些檔案的資料全部合併到一個文字檔案中,共用同一個表頭。
示例:在e:/orders目錄下有每日的訂單文字檔案,每個檔案的結構相同,第一行是列名,第二行開始是資料,如下圖所示,請將它們合併成一個訂單表檔案orders.txt。
esProc SPL指令碼如下:
|
A | 註釋 |
1 | =directory@p("e:/orders/*.txt") | 返回orders目錄所有txt檔案的完整路徑名 |
2 | =A1.conj(file(~).import@t()) | 合併所有檔案的資料 |
3 | =file("e:/orders.txt").export@t(A2) | 將合併後的資料寫入orders.txt檔案 |
如果e:/orders還有子目錄,子目錄中的txt檔案也需要一起合併,那麼把A1格改成=directory@ps("e:/orders/*.txt"),選項@s表示遞迴查詢所有子目錄下的檔案。
上面這段指令碼是假設記憶體能夠裝下合併以後的全部資料,如果裝不下,那麼應該用下面這段指令碼:
|
A | B | C |
1 | =directory@p("e:/orders/*.txt") | =file("e:/orders.txt") |
|
2 | for A1 | =file(A2).cursor@t() |
|
3 |
|
if #A2==1 | =B1.export@t(B2) |
4 |
|
else | =B1.export@a(B2) |
A1 列出目錄中的所有txt檔案的完整路徑名稱,如果要查詢子目錄,則加上@s選項
A2 對列出的檔案進行迴圈
B2 用遊標讀取每一個檔案,@t表示第一行是列名
B3-C4 將B2遊標中資料匯出,第一次要匯出列名,其後用@a進行追加
2. 結構近似的文字檔案合併
如果檔案結構並不是完全相同,比如列的順序不一樣、列數不一樣,但各檔案都含有共同的幾列,想要把這些共同列的資料都合併到一個檔案中。合併這些檔案時,需要按指定順序讀出每個檔案中的這些共同列資料。
示例:還是上面這個例子,已知所有訂單檔案都有ID、Company、Area、OrderDate、Amount這5列,但各檔案中列的順序並不相同,有的檔案還有其它一些列,請將各檔案中的這5列資料合併到orders.txt檔案中。
esProc SPL指令碼如下:
|
A | 註釋 |
1 | =directory@p("e:/orders/*.txt") | 返回orders目錄所有txt檔案的完整路徑名 |
2 | =A1.conj(file(~).import@t(ID,Company,Area,OrderDate,Amount)) | 按指定的5列順序讀出各檔案資料,然後合併所有檔案的資料 |
3 | =file("e:/orders.txt").export@t(A2) | 將合併後的資料寫入orders.txt檔案 |
同樣地,如果記憶體裝不下合併後的所有資料,則使用下面這段指令碼:
|
A | B | C |
1 | =directory@p("e:/orders/*.txt") | =file("e:/orders.txt") |
|
2 | for A1 | =file(A2).cursor@t(ID,Company,Area,OrderDate,Amount) |
|
3 |
|
if #A2==1 | =B1.export@t(B2) |
4 |
|
else | =B1.export@a(B2) |
3. 檔名轉成列資料
在合併資料的同時,需要為合併後的資料增加一列,並用合併前的檔名給此列賦值,以便標記資料類別或來源。
示例:在e:/orders目錄下有各種零件的訂單Excel檔案,檔名就是零件的名字,比如tyre.xlsx、engine.xlsx……等,每個檔案的結構相同,第一行是列名,第二行開始是資料,如下圖所示,請將它們合併成一個訂單表檔案orders.xlsx,並增加一列PartName用來記錄零件的名字。
esProc SPL指令碼如下:
|
A | 註釋 |
1 | =directory@p("e:/orders/*.xlsx") | 返回orders目錄所有Excel檔案的完整路徑名 |
2 | =A1.conj((fn=filename@n(~),file(~).xlsimport@t().derive(fn:PartName))) | 先將檔名定義為臨時變數fn,讀入檔案後,增加一列PartName,並用fn賦值。最後將各檔案資料合併 |
3 | =file("e:/orders.xlsx").xlsexport@t(A2) | 將合併後的資料寫入orders.xlsx檔案 |
同樣地,如果記憶體裝不下合併後的所有資料,則使用下面這段指令碼:
|
A | B | C |
1 | =directory@p("e:/orders/*.xlsx") | =file("e:/orders.xlsx") |
|
2 | for A1 | =file(A2).xlsimport@tc().derive(filename@n(A2):PartName) |
|
3 |
|
if #A2==1 | =B1.xlsexport@ts(B2) |
4 |
|
else | =B1.xlsexport@as(B2) |
合併後的orders.xlsx檔案部分資料如下圖所示:
二、 檔案拆分
1. 分組拆分
對檔案中資料進行分組,把每組資料單獨存為一個檔案,用組名為檔案命名。
示例:在訂單表Excel檔案中有各種零件的訂單,請把同種零件的訂單各存為一個Excel檔案,以便傳送給零件生產部門。
esProc SPL指令碼如下:
|
A | B |
1 | =file(“e:/orders/orders.xlsx”).xlsimport@t() | =A1.group(partName) |
2 | for B1 | =file("e:/parts/"+A2(1).partName+”.xlsx”).xlsexport@t(A2) |
A1 讀入所有原始資料
B1 按partName分組
A2 迴圈每個零件組的訂單資訊
B2 以零件名稱作為檔名,匯出零件資訊
如果原檔案很大,不能全部裝入記憶體,那麼應該使用遊標方式讀數,指令碼如下:
|
A | B | C | D |
1 | =file(“e:/orders/orders.xlsx”).xlsimport@tc() | |||
2 | for A1,50000 | =A2.group(partName) |
|
|
3 |
|
for B2 | =file("e:/parts/"+B3(1).partName+”.xlsx”) |
|
4 |
|
|
if C3.exists() | =C3.xlsexport@a(B3) |
5 |
|
|
else | =C3.xlsexport@t(B3) |
A1 建立遊標讀取原始資料
A2 迴圈遊標讀數,每次讀50000行(讀多少行根據記憶體大小決定)
B2 對每次讀取的資料按partName分組
B3 迴圈每組零件
C3 以零件名稱作為檔名建立檔案物件
C4-D5 如果檔案已存在,則用@a追加寫入零件訂單資訊,不存在則用@t先寫入列名再匯入資料
2. 記錄佔據多行的拆分
在文字檔案中,一條資料記錄是由多行資料組成的,在拆分成小檔案時,要識別哪幾行是同一條資料記錄,保證同一條資料記錄不會被拆分到兩個檔案中。
示例1:有網站執行日誌檔案log.txt,每條日誌由5行組成,現在需要把這個日誌檔案拆分成一些小檔案,每個檔案由1000條日誌組成。
esProc SPL指令碼如下:
|
A | B |
1 | =file(“e:/log.txt”:”UTF-8”).cursor@s() |
|
2 | for A1,5000 | =file(“e:/log/log_”/#A2/”.txt”).export(A2) |
A1 用遊標讀取日誌檔案資料,@s表示將整行讀成一個字串
A2 迴圈遊標,每次取5000行,剛好是1000條日誌
B2 按迴圈序號生成日誌檔名,如log_1.txt、log_2.txt……,然後將當前取出的所有行寫入
示例2:有程式執行日誌檔案log.txt如下圖所示,每條日誌由不確定的幾行組成,每條日誌由中括號開頭,其後只要不是中括號開頭的行,都與它屬於同一條日誌。現在需要把這個日誌檔案拆分成一些小檔案,每個檔案由1000條日誌組成。
esProc SPL指令碼如下:
|
A | B |
1 | =file(“e:/log.txt”:”UTF-8”).read@n() | =A1.select(~!="") |
2 | =B1.group@i(pos(~,"[")==1).cursor() |
|
3 | for A2,1000 | =file(“e:/log/log_”/#A3/”.txt”) |
4 |
|
=A3.(~.(B3.write@a(~))) |
A1 開啟日誌檔案讀取資料,@n表示將每一行讀成一個字串,所有串組成一個序列返回
B1 篩選出非空的行
A2 按行是否用中括號開頭作為分組條件,中括號開頭的作為一個新組,不是則併到當前組。最後把所有組序列轉換成遊標
A3 迴圈遊標,每次取1000個組,即1000條日誌
B3 按迴圈序號生成日誌檔名,如log_1.txt、log_2.txt……
B4 兩層迴圈,外層是迴圈1000個組,內層迴圈每組的成員(即資料行),將每行追加寫入檔案
《 》中有更多相關計算示例。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69957599/viewspace-2735044/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- linux檔案合併、去重、拆分Linux
- java 拆分與合併字串Java字串
- Goldengate的拆分與合併Go
- 命令列中的拆分與合併命令列
- Git 合併指定檔案或資料夾Git
- opencv 影像的 ROI、通道的拆分與合併OpenCV
- Oracle 11g 分割槽拆分與合併Oracle
- Aspose.Words使用教程之如何寫入純文字(TXT)檔案,表的合併與拆分
- Pandas之EXCEL資料讀取/儲存/檔案分割/檔案合併Excel
- windows合併檔案Windows
- 合併iso檔案
- 請求合併與拆分在併發場景中應用
- 合併與拆分資料模型(MSDM:Merging & Spliting Data Modeling)模型
- Linux大檔案的切割與合併Linux
- linux下檔案分割與合併 (轉)Linux
- linux下檔案分割與合併(轉)Linux
- Hive小檔案合併Hive
- Linux檔案分割與合併:split&catLinux
- requireJS對檔案合併與壓縮(二)UIJS
- Linux - 檔案的分割(split)與合併(cat)Linux
- linux下檔案的切割與合併(轉)Linux
- PDFsam Basic for mac合併拆分PDF文件Mac
- Linux下合併檔案Linux
- python實現將資料夾內所有txt檔案合併成一個檔案Python
- git合併分支,如果選擇性的合併檔案?Git
- 如何在 Acrobat Pro DC 與其它檔案合併建立單個 PDF 檔案?BAT
- 檔案與資料
- java快速分割及合併檔案Java
- shell 檔案合併 去重 分割
- 檔案切割以及合併筆記筆記
- Python之合併PDF檔案Python
- 超級檔案分割《合併》機(分割大檔案)
- 辦公自動化:PDF檔案合併器,將多個PDF檔案進行合併
- Mac如何使用預覽應用合併PDF檔案 Mac合併PDF檔案教程詳解Mac
- 合併PDF檔案怎樣做?分享兩種PDF合併方法
- PDF轉換器可以做到PDF轉Office,TXT,HTM,PDF檔案;PDF合併拆分,壓縮,加密解密!加密解密
- 多個 EXCEL 檔案如何合併成一個檔案Excel
- Linux下檔案的切分與合併的簡單方法Linux