2012-05-31 112 views
1

我有兩個文件如何比較兩個大文件並獲得第三個文件的結果?

一號文件是這樣的:

www.example.com 
www.domain.com 
www.otherexample.com 
www.other-domain.com 
www.other-example.com 
www.exa-ample.com 

第二個文件是這樣的(數字之後是0-10之間;;;):

www.example.com;;;2 
www.domain.com;;;5 
www.other-domain;;;0 
www.exa-ample.com;;;4 

和我希望這兩個文件,並輸出到第三文件比較是這樣的:

www.otherexample.com 
www.other-example.com 

兩個文件H AVE大尺寸(超過500MB)

+0

第二個文件中是否還有第一個文件中不存在的域名?還是足以輸出第一個不存在於第二個域中的域? –

回答

0

您可以使用:

$ diff file1 file2 > file3 

但它接縫我要不顧;;0一部分,對不對? 然後,你需要通過線剝離的最後一部分線處理它,最後,用diff

+0

回覆:「逐行刪除最後一部分」:可以用'<(cut -d';'-f1 file2)'替換'file2'來完成。 – ruakh

0

比較你可以使用diff命令,並直接輸出到3第三個文件。例如,

% diff data1.txt data2.txt > diffs 

diff man page示出了一些,使您可以比較(處理和輸出)控制選項。

沒有指定選項的基本交互操作,假設你有你的文件data1.txtdata2.txt產量您的文章顯示的數據:

% diff data1.txt data2.txt 

1,6d0 
< www.example.com 
< www.domain.com 
< www.otherexample.com 
< www.other-domain.com 
< www.other-example.com 
< www.exa-ample.com 
+0

與差異我得到的消息:差異:內存耗盡 –

+1

@MartinMocik也許你可以嘗試'rdiff'根據這個職位:http://beerpla.net/2008/05/12/a-better-diff-or-what- gnu-diff-runs-out-of-memory-diff-memory-exhausted/ – Levon

0

如果a是與第一內容的文件和b是帶有第二個內容的文件:

while read line; do grep -q $line b || echo $line; done < a 

它打印在第二個文件中找不到的文件。

+0

對於一組500MB的文件,這將會非常慢。 –

+0

當然,但它的作品。這是一個簡單的C程序的好起點 –

4

使用comm(1)比較兩個排序文件並給出差異。使用grep(1)sort(1)將您的文件轉換爲適合與comm進行比較的輸入格式。使用進程替換bash綁一起:

comm -23 <(sort file1.txt) <(grep -o '^[^;]*' file2.txt | sort) 

-23參數comm說忽略兩者共同文件(-3)和行唯一的行到文件2(-2)。根據您的確切規格,您可以使用-1-2-3

grep -o '^[^;]*' file2.txt剛剛剝去第一個分號後的所有內容。您可以使用sed(1),但如果您只提取一行的一部分而不添加其他內容,grep通常會更快。

comm需要輸入文件進行排序,所以sort是用來做到這一點。輸出將被排序。sort使用語言環境特定的排序規則,因此您可能需要根據所需的精確排序規則設置LC_ALL = C。

請注意,在您的問題中,您在文件2中有www.other-domain,但在文件1中有www.other-domain.com。我認爲它是給定輸出的文件2中的拼寫錯誤。

這將並行運行所有進程並通過它們傳輸文件數據,因此即使文件很大,也不會佔用大量內存或任何額外的磁盤空間來存儲臨時文件。

+0

在我的系統上,花了'grep'花費的時間是'sed'的1/8。對於900KB的GNU'grep'文件,'time sed'/..////'文件名>/dev/null'與'time grep -o'^ [^;] *'filename>/dev/null' 2.5.4和GNU'sed' 4.2.1 –

+0

@ DennisWilliamson:有意思。在過去,我的工作速度快了很多。感謝您的數據。 – camh

+0

很大程度上取決於數據和其他因素。我有'grep'foo'|對於更復雜的「foo」,awk'{...}'比'awk'/ foo/{...}'快得多。 –

3

如果file2輸入中包含的file1內容的子集,你可以只

sed 's/;.*//' file2 | fgrep -vxf - file1 >not-in-file2 

同樣的總體思路可以應用到diffcomm。但是,comm需要排序輸入,但如果這不是問題(或者您的數據可以從開始排序),則只需預處理file2中的數據。

sed 's/;.*//' file2.sorted | comm -12 - file1.sorted >cmp.out 

該輸入需要進行排序的約束是什麼讓comm處理真正大型文件,因爲它只是需要保持最新的數據在內存中的任何一個時間。你可以用你自己的awk腳本來做同樣的事情。

相關問題