我確信有人有以下需求,按行分割巨大的 .gz 檔案的快速方法是什麼?底層文字檔有 1.2 億行。我沒有足夠的磁碟空間來一次壓縮整個文件,所以我想知道是否有人知道 bash/perl 腳本或工具可以將文件(.gz 或內部 .txt)拆分為 3x 40mn 行文件。即這樣稱呼它:
bash splitter.sh hugefile.txt.gz 4000000 1
would get lines 1 to 40 mn
bash splitter.sh hugefile.txt.gz 4000000 2
would get lines 40mn to 80 mn
bash splitter.sh hugefile.txt.gz 4000000 3
would get lines 80mn to 120 mn
也許正在做一系列這些解決方案,或者 Gunzip -c 需要足夠的空間來解壓縮整個檔案(即原始問題):前 4000000
注意:我無法獲得額外的磁碟。
謝謝!
答案1
如何最好地做到這一點取決於您想要什麼:
- 您想提取大檔案的單一部分嗎?
- 或者您想一次創建所有部件?
如果你想要一個文件的單一部分,你的想法gunzip
是head
正確的。您可以使用:
gunzip -c hugefile.txt.gz | head -n 4000000
這將在標準輸出上輸出前 4000000 行 - 您可能想要附加另一個管道來實際對資料執行某些操作。
head
要取得其他部分,您可以使用和的組合tail
,例如:
gunzip -c hugefile.txt.gz | head -n 8000000 |tail -n 4000000
獲得第二個區塊。
也許是做一系列這些解決方案,或者 Gunzip -c 需要足夠的空間來解壓縮整個文件
不,gunzip -c
不需要任何磁碟空間 - 它在記憶體中執行所有操作,然後將其串流傳輸到標準輸出。
如果你想創建所有零件一氣呵成,使用單一命令建立它們會更有效,因為這樣輸入檔案只會被讀取一次。一個好的解決方案是使用split
;有關詳細信息,請參閱吉姆·麥克納馬拉的回答。
答案2
要分割的管道使用gunzip -c或zcat開啟文件
gunzip -c bigfile.gz | split -l 400000
將輸出規格新增至 split 命令。
答案3
當您處理(不可倒回)流時,您將需要使用 tail 的「+N」形式來取得從第 N 行開始的行。
zcat hugefile.txt.gz | head -n 40000000
zcat hugefile.txt.gz | tail -n +40000001 | head -n 40000000
zcat hugefile.txt.gz | tail -n +80000001 | head -n 40000000
答案4
直接將 .gz 檔案拆分為 .gz 檔案:
zcat bigfile.gz | split -l 400000 --filter='gzip > $FILE.gz'
我想這就是OP想要的,因為他沒有太多空間。