UNIX 文字工具: 唯一或重複

如果想要去除一個檔案中重複的列,可以用 uniq 指令。 但是 uniq 假設它的輸入檔案是被排序過的,所以一定要先 sort 檔案, 才能交給 uniq 去執行。 但是讀者要小心,某些情況下,我們在螢幕上看起來同樣內容的兩列, 可能對電腦而言並不相同。 例如一列尾端的連續空白,是眼睛看不出來的。 還有跳格造成的空白,與空格造成的空白,是眼睛看不出來的, 但電腦卻認為它們不同。 所以,此處所謂的「相同的兩列」不是指螢幕上看起來的樣子, 而是指對電腦而言,這兩列的每一對對應字元都相同。

為了做實驗,我們先製造一個有許多重複列的檔案出來。

head forty.txt > twenty.txt
head -20 forty.txt | tail -10 | sed 's/and //' >> twenty.txt
這個新檔案 twenty.txt 的內容是
ne little
two little
three little Indians
four little
five little
six little Indians
seven little
eight little
nine little Indians
ten little Indian boys
one little
two little
three little Indians
four little
five little
six little Indians
seven little
eight little
nine little Indians
ten little Indian girls
可見第 11--19 列和第 1--9 列是重複的,只有第 10 和第 20 列是唯一的。

要把 twenty.txt 裡面的所有列只印一次出來,下指令

sort twenty.txt | uniq
也就是說,重複的列只各印一次,唯一的列也是印一次。 所以共有 11 列。 前面那個指令等同於
sort -u twenty.txt
它們的結果都是
eight little
five little
four little
nine little Indians
one little
seven little
six little Indians
ten little Indian boys
ten little Indian girls
three little Indians
two little

如果只要找到檔案中重複的列,可以用 uniq 的指令參數 -d (duplicated):

sort twenty.txt | uniq -d
如果要計算每列出現的次數,可以用參數 -c (count):
sort twenty.txt | uniq -c
結果應該是:
   2 eight little
   2 five little
   2 four little
   2 nine little Indians
   2 one little
   2 seven little
   2 six little Indians
   1 ten little Indian boys
   1 ten little Indian girls
   2 three little Indians
   2 two little
如果只要印出重複的列,和其重複次數,可以利用 awk 來處理:
sort twenty.txt | uniq -c | awk '$1!=1'
前面已經引介過 awk 了。現在再稍微解釋一下。 在 awk 的語言裡面,$1 代表每列的第一個字,!= 代表不等於, 所以就是印出第一個字不是 1 的那些列。

如果只要找到檔案中唯一的列,可以用參數 -u (unique):

sort twenty.txt | uniq -u
結果應該是結果應該是:
ten little Indian boys
ten little Indian girls

有人或許要問,怎樣把一個檔案中重複的列,只保留第一次出現的那一列, 其他都重複,而且整個檔案保持原來的順序呢? 類似的問題是,怎樣把檔案中唯一出現的列都刪除掉,只留下重複出現的列, 並且保持原檔案內的列順序呢? 前面的方法雖然可以把重複的列或唯一的列都找出來, 卻沒有辦法保持原檔案的順序,因為它們都經過 sort。 這類問題的解,需要配合列編輯器 ed 或 ex 使用。我們不在這裡深談。

習題

[ 前一節 ]‧[ 後一節 ]‧[ 回目錄 ]



注意:此處所有文件均為原著,個別的版權宣告日後會一一公布, 整體版面設計亦尚未完成。但仍請勿抄襲文字與圖片,以免觸犯著作權法。

Created: Nov 20, 2000
Last Revised: Nov 20, 2000
© Copyright 2000 Wei-Chang Shann 單維彰

shann@math.ncu.edu.tw