2013-04-03 66 views
0

我正在嘗試使用Perl中的程序刪除重複的條目。說此Perl單線程所需的解釋

File : abc 
11 
22 
11 
11 
22 
33 

輸出應該是:

11 
22 
33 

一個Perl one-liner使我的工作容易。但我無法理解它。它是:

cat abc | perl -ne '$H{$_}++ or print' 

一些基本的知識,我假定「ABC的輸出是由線傳遞線,他們正在推動它變成一個哈希......但什麼-ne代表什麼爲什麼他們用++? ?什麼是or說法?有什麼解釋?

有沒有一種方法,我可以找到出現的次數也?

11 - 3 
22 - 2 
33 - 1 
+2

一種你最後一個問題oneliner是'貓ABC | perl -ne'$ H {$ _} ++;對於排序鍵%H,END {print「$ _ - $ H {$ _} \ n」; }'' –

+0

@Stefan:這太棒了:) – kailash19

+0

貓的無用用法:-)(在最初的例子和Stefan的評論中) –

回答

3

你是正確的,到目前爲止,這個管道文件abc到使用散列的perl命令。要了解-ne說法,將其比作這個代碼是幾乎等同,

while (<>){ 
    $H{$_}++ or print $_ 
} 

要明確,我也改變printprint $_

現在這個單線程工作的原因是因爲當通過執行$H{$_}++遞增密鑰的哈希值時,我們得到了密鑰關聯值的返回值。

我們第一次遇到密鑰(行abc)時,它在哈希中的值默認爲0。因此,or子句尚未滿足,它將繼續到print $_(打印該行)。但在隨後的任何時間我們遇到一個密鑰,它的返回值將是>0所以or子句將短路因爲Perl中的任何正整數評估爲true

什麼有趣的是,這一個班輪將不行,如果我們不是把它寫這樣的:

cat abc | perl -ne '++$H{$_} or print' 

這是因爲我們在這裏預遞增和值將是在後我們遞增

+1

如果你來自那些控制流傳統上用if分支和循環處理的語言,那麼'或'可能會很奇怪。還有一些其他慣用的Perl語句涉及到它,例如'open(HANDLE,$ filename)或者die「無法讀取$ filename」。閱讀這些可能會幫助你更好地掌握'或'。還有''和'的東西,最突出的是叉子和出口;'。 –

3

命令行選項-n圍繞-e代碼循環。如果你輸入的東西,如:

$ perl -n -e 'some code' file 

那麼Perl會解釋,由於:

LINE: 
    while (<>) { 
     # your code goes here, each iteration reads 
     # from file and puts into $_ variable 
    } 

文件在你的例子是來自cat命令的輸出管道。

$H{$_}++ or print $_; 

這會創建一個散列,將文件的行作爲關鍵字。如果該鍵不存在,則它將對1值進行賦值,否則以後遞增。第一次($ H {$ _} ++)被計算爲false,因此Perl將執行右或右句子。這是一樣的:

print $_ unless $H{$_}++; 
0

開關ne手段:

-e =此命令行開關可以在命令行中運行代碼, 而不是你的程序寫的一個文件然後執行它。

-n =此命令行開關允許您針對標準輸入上的每一行運行程序(通常用-e指定)。

所以這就是如何逐行輸出處理。

現在,對於哈希值,如果新值來了,因爲它不存在被打印,但下一次增加並且由於或條件而不打印該值。

爲了找到出錯的人數,我不確定如何處理perl一個班輪,腳本將會很容易。

ü也可以做的非常簡單地使用sort和uniq在Linux中:

cat abc |sort | uniq -c 
0

計數例如:

cat abc | perl -nle'$H{$_}++ ; END { for (keys %H) { print "$_ - $H{$_}" } }'