2016-05-17 63 views
0

我正在處理一個問題,我必須用大量文本文件中的某些行替換另一個(較小但仍然很大)的文本文件。Bash - 有效替換大文本文件中的小範圍行

假設file1有10,000行,file2 3,000行。我需要執行以下類型的操作:從file2中提取901-970行,並將其插入file1的8701-8770行,替換之前的內容。在我正在處理file1的問題中,有6100萬行,文件2 1800萬。我需要這個操作高效地完成,因爲它執行了多次 - 最終,file2的全部內容將在file1中的某處。

目前爲止我所得到的最佳解決方案是將兩個文件分成小文件,每個文件都有被複制和替換的塊的行數(上例中爲70)。事實證明,這比用頭部和尾部組合提取文件的一部分要高效得多,但仍然需要觸及未修改的file1部分。

我想知道是否有這樣的awk/grep/sed解決方案。提取file2的一部分不是問題,但我無法弄清楚如何在不加載整個文件的情況下替換file1的一行代碼塊。

謝謝!

+0

你可以將文件分割成偶數行。例如:File1_1(1-900),File1_2(901_970),File1_3(971_)以及類似的File2。然後加入這些部分。 File1_1,File2_1,File1_3等。如果您的部分很大,則表示部分的數量可以管理。 – karakfa

+0

如果您的字面意思是按行數進行處理,或者如果這只是向我們展示問題範圍的近似值,但您確實需要掃描特定的字符串以標記將發生替換的位置,則應明確說明。祝你好運 – shellter

+0

@karafka這也是一種可能性,但由於我需要在整個文件中做幾次替換,所以我仍然有大量的節。謝謝。 – Albertini

回答

1

問題是,您必須執行隨機訪問類型的操作(與順序處理不同),以「避免觸及」不會更改的file1部分,並且文件的隨機訪問是在字符/字節級別,而不是行級別。也就是說,如果在file1中被替換的字節(與行相對)的數量與來自file2的字節的數量相同,則可以這樣做(使用fseek等)。但這聽起來像是沒有辦法保證?

因此,無論如何,您將不得不對單個文件進行一次遍歷,因此該鍵將優化循環內的處理(通過file1行)。考慮用file1處理所有的文件2? (而不是涉及兩個文件的多個操作)。

+0

實際上,file1中被替換的字節數與來自file2的字節數相匹配,所以我可以按照您的建議使用隨機訪問操作 - 我沒有意識到這是我的問題的可能性。我用dd從file2中提取了塊,並在file1中進行了替換 - 與我之前做的分割文件相比,這大約快了30%。 感謝您的幫助! – Albertini

+0

@ D.Puetzer酷!看到完整的「dd」命令會很有意思,並且所有未來在這個問題上出現的其他人都可以在類似問題上獲得快速啓動。 –

+0

完成,再次感謝。 – Albertini

1

遵循Jeff Y的建議,我使用dd命令在字節級有效地進行了替換。我首先使用從file2的提取塊:

dd if="file2" bs="$bperelem" skip="$start_copy" count=1 of="tmp2" 2> /dev/null 

其中bperelem是塊的字節,並start_copy數爲所在的位置。然後,我用下面的代碼替換到這個文件1:

dd if="tmp2" bs="$bperelem" skip=0 count=1 seek="$start_replace" of="file1" conv=notrunc 2> /dev/null 

對於我的特定問題的變量start_copystart_replace是一個while循環中更新。