2012-06-18 34 views
5

當前進程:提取從tar.gz的文件,不接觸磁盤

  1. 我有一個tar.gz文件。 (其實,我有大約2000人,但那是另一回事)。
  2. 我建立一個臨時目錄,提取tar.gz文件,顯示100,000個小文件(每個大約600字節)。
  3. 對於每個文件,我將它編入一個處理程序,將其導入另一個分析程序並保存結果。

我正在使用的機器上的臨時空間幾乎無法同時處理這些進程中的一個,不必介意它們默認發送的16個(超線程雙核四核)。 我正在尋找一種方法來執行此過程而不保存到磁盤。我相信單獨使用tar -xf $file -O <targetname>提取文件的性能損失會令人望而卻步,但它可能是我堅持的。

有沒有辦法做到這一點?

編輯:既然兩個人已經犯了這個錯誤,我要澄清:

  • 每個文件代表了一個時間點。
  • 每個文件都單獨處理。
  • 一旦處理完畢(在這種情況下,傅里葉分析中的變體),每個都會給出一行輸出。
  • 這個輸出可以結合起來做一些事情,比如隨着時間的推移自相關。

EDIT2:實際代碼:

for f in posns/*; do 
    ~/data_analysis/intermediate_scattering_function < "$f" 
done | ~/data_analysis/complex_autocorrelation.awk limit=1000 > inter_autocorr.txt 
+0

什麼是未壓縮的文件的總大小?你有多少ram? –

+0

100K文件* 4KB最小文件大小= 400MB。我有16 GB,所以16不會有太多問題。 – zebediah49

+0

那麼,我打算告訴你使用一個ramdisk,但@Harald Brinkhof已經做了:) –

回答

4

這聽起來像是一個正確的工具可能不是shell腳本的情況。 Python有一個tarfile模塊,它可以在流模式下運行,讓您只需一次通過大型壓縮文件並處理其文件,同時仍能夠區分單個文件(其中tar --to-stdout方法不會)。

+0

在python中重寫了分析代碼;它運行了幾分鐘而不是幾個小時。 – zebediah49

5

如果你不關心文件之間的邊界,然後tar --to-stdout -xf $file會做你想要的東西;它會將檔案中每個文件的內容一個接一個地發送到stdout。

這裏假定你使用的是GNU tar,如果你使用bash,這很有可能。

[更新]

既然你想單獨處理每一個文件,我同意查爾斯·達菲是一個shell腳本是錯誤的工具的限制。

你可以試試他的Python建議,或者你可以試試Archive::Tar Perl module。這些都可以讓你遍歷內存中tar文件的內容。

+0

不幸的是我做到了;每個目標文件都必須單獨處理..其輸出結合起來。 – zebediah49

+0

+1這將節省創建'100000'貓進程的開銷。這是節省了很多開銷。 – Paulpro

4

您可以使用tar選項--to-command=cmd爲每個文件執行的命令。 Tar將文件內容重定向到命令的標準輸入,並設置一些有關該文件的詳細信息的環境變量,例如TAR_FILENAME。更多詳細信息在Tar Documentation

例如

tar zxf file.tar.gz --to-command='./process.sh' 

請注意,OSX默認使用bsdtar,它沒有此選項。您可以明確地調用gnutar

+0

不錯!這是我不知道的。 :) –

0
tar zxvf <file.tar.gz> <path_to_extract> --to-command=cat 

上述命令將顯示提取的文件的僅上殼的內容。磁盤將不會發生變化。 tar命令應該是GNU tar。

抽樣日誌:

$ cat file_a 
aaaa 
$ cat file_b 
bbbb 
$ cat file_c 
cccc 
$ tar zcvf file.tar.gz file_a file_b file_c 
file_a 
file_b 
file_c 
$ cd temp 
$ ls <== no files in directory 
$ tar zxvf ../file.tar.gz file_b --to-command=cat 
file_b 
bbbb 
$ tar zxvf ../file.tar.gz file_a --to-command=cat 
file_a 
aaaa 
$ ls <== Even after tar extract - no files in directory. So, no changes to disk 
$ tar --version 
tar (GNU tar) 1.25 
... 
$