2012-06-05 43 views
3

我想使用Linux命令從大選項卡分隔文件中刪除重複單詞/字符串。刪除選項卡分隔文件中的重複單詞/字符串

names   john, cnn, mac, tommy, mac, patrick, ngc, discovery, john, cnn, adam, patrick 
cities   san jose, santa clara, san franscisco, new york, san jose, santa clara 

以上是文件格式,我想在刪除重複的單詞後保留製表符和逗號。

names   john, cnn, mac, tommy, patrick, ngc, discovery, adam 
cities   san jose, santa clara, san franscisco, new york 

任何幫助,將不勝感激。

+0

是名重要的訂單? –

+0

不,但選項卡和逗號很重要。 – Kaartz

回答

3
awk 'BEGIN { 
     FS = ", |\t" 
    } 
    { 
      printf "%s\t", $1 
      delim = "" 
      for (i = 2; i <= NF; i++) { 
       if (! ($i in seen)) { 
        printf "%s%s", delim, $i 
        delim = ", " 
       } 
       seen[$i] 
      } 
      printf "\n" 
      delete seen 
    }' inputfile 

如果你不使用GNU AWK(gawk),那麼你不能delete陣列,使用split("", array)代替。

+0

非常感謝Dennis。你的腳本就像一個魅力!但在輸出標籤消失了,我得到一個逗號與空間。 name,john,cnn,mac,tommy,patrick,ngc,discovery,adam – Kaartz

+0

@Kaartz:很奇怪。它適用於我。仔細檢查以確保輸入文件具有選項卡。另外,請確保您在我的答案中使用了當前版本的腳本。在發佈沒有它的第一個版本後,我很快添加了'delim'功能。你使用的是什麼版本的AWK?什麼操作系統/分佈? –

+0

我通過添加printf「%s \ t \ t \ t \ t」$ 1來修復它。非常感謝你的這個劇本。 – Kaartz

2

sedawk本身並不特別適合這個。 uniq比較好。

首先將名稱拉出到另一個文件中,比如names。您可以爲此使用SED:

head -1 inputfile | sed 's/^names\s*//g' > names 

所以,現在的名稱包含john, cnn, mac, tommy, mac, patrick, ngc, discovery, john, cnn, adam, patrick

然後使用此:

awk 'BEGIN{RS=","}{print $0}' names | sort | uniq | awk 'BEGIN{ORS=","}{print $0}' 

輸出是adam,cnn,discovery,john,mac,ngc,patrick,tommy,。如果您想使用sed,也可以刪除最後一個逗號。當然,您也可以將head命令的輸出傳遞給第二個awk。在這種情況下,您將不需要中間文件names

同樣適用於城市。我假設訂單對你來說並不重要。

+0

'sort | uniq'可以在大多數linux盒子上用'sort -u'代替。我不知道這是如何在Unix上移植的,它適用於我的Solaris機器。 – rahmu

0

這可能會爲你工作:

sed -i ':a;s/\(\(\<[^,]*\),.*\)\(\2,*\)/\1/;ta;s/,$//' /tmp/a