2013-12-20 32 views
6

我想找到兩個文件(大的)之間的共同線,一個有9000萬行,1個有10萬行,還有他們的行號。找到兩個文件之間的共同線和他們的行號

comm -12 file1 file2 

給我的共用線,但我想知道從單個文件以及行號

+0

你的意思是說有10萬行的人已經有行號了嗎? – bryn

+3

那麼如果一行發生在文件1中的第300行和文件2中的第500行,你期望輸出什麼?那麼如果它在文件2中的第600行再次出現呢? –

+0

@MarkSetchell 300 commonline 500 – user31641

回答

0

你可以試試:

awk ' 
FNR==NR { 
    a[$0]++ 
    next 
} 
$0 in a { 
    print 
    delete a[$0] 
}' file1 file2 

如果你也想獲得線數字,你可以在gawk版本4中使用陣列陣列,如:

FNR==NR { 
    a[$0][FNR]++ 
    file1=FILENAME 
    next 
} 
FNR==1 { 
    file2=FILENAME 
} 

$0 in a { 
    b[$0][FNR]++ 
} 

END { 
    for(i in b) { 
     print "Line: " i 
     print " Line numbers in "file1":" 
     printf " " 
     for (j in a[i]) 
      printf "%s,", j 
     print "" 
     print " Line numbers in "file2":" 
     printf " " 
     for (j in b[i]) 
      printf "%s,", j 
     print "" 
    } 
} 
0

你可以在那裏得到一半diff。這向您顯示了file1中的行號,但不幸的是,似乎沒有任何選項可顯示file2的行號 - 看起來man diff假定在兩個文件中都有一個不變的行也在相同的行上,即違背了它通常的工作原理。

diff --unchanged-line-format=$'%dn\t%L' --old-line-format='' --new-line-format='' file1 file2 

使用unified diff另一半招:

diff -u file1 file2 

這說明不同線,有點背景的,這意味着你可以推斷共同文本上線。以@@開頭的行會爲您提供行信息。例如:

@@ -1,5 +2,10 @@ 

這意味着先從-或在差異中的空間是在file1線1,並且將下一行開始+或空間處於file2線2中的下一行。爲了您的目的,您可以忽略逗號後的數字。

2

該解決方案適用於我的小測試文件 - 我不確定它如何在具有9000萬行的文件上執行。

tab=` printf '\t' ` 
join -t"$tab" -j2 <(cat -n file1) <(cat -n file2) 

這工作,因爲cat -n一個前加空格填充數字後跟製表符每行。 join然後找到只在第一個選項卡後的東西的共同線。

連接完成後,您應該看到公用線,每個公用線後跟兩個數字。第一個數字是來自file1的行號,第二個來自file2。

警告:如果文件中沒有製表符,這將起作用。如果不是這種情況,您可以使用sed將第一個選項卡轉換爲「安全」字符。

safe="|" 
join -t"$safe" -j2 \ 
    <(cat -n file1 | sed -e "s:\t:$safe:") \ 
    <(cat -n file2 | sed -e "s:\t:$safe:") 

另外,根據join是如何實現的,你可能想在第一進程替換列出的更小的文件和較大的一個第二。通過這種方式,較小的文件可能全部適合內存,較大的文件可能會被掃描,並且有效地選擇匹配的行。我不知道情況是否如此,但可能值得一試。

+0

+1這是一件好事,在問題中添加更多想法可能很有趣,但是我希望您也可以考慮發佈問題的時間,以及如果OP仍然在意他的問題,也許你可能不會浪費你的精力。乾杯。 – konsolebox

+3

部分我爲了聲望和部分磨練:http://xkcd.com/979/ –

+0

我已經多次提及XKCD ..你有我的弓,我的斧頭和我的upvote。 –

相關問題