2016-12-16 510 views
1

我有一個包含數千行文本的文本文件,其中包含域名列表,後面是具有不同信息的時間段(數字,空格和其他信息)如何用sed刪除部分重複的行?

某些域的值可能超過1行信息,具有不同數量和信息之後,如在本例中結構域1和4

domain1.foo. 3600 ... 
domain1.foo. 1800 ... 
domain2.foo. 900 ... 
domain3.foo. 60 ... 
domain4.foo. 3600 ... 
domain4.foo. 1200 ... 
domain4.foo. 1200 ... 

重複的選只會是彼此下方線(例如,涉及domain4線可以是線50,51,52 ,但從來沒有50,60和400)。

所以我試圖做的就是創建用sed刪除包含每個域名,不管以後會發生什麼任何重複的行 - 因此,例如將成爲

domain1.foo. 3600 ... 
domain2.foo. 900 ... 
domain3.foo. 60 ... 
domain4.foo. 3600 ... 

我只是有一個基本知識正則表達式,並希望得到一些有關如何去做這件事的幫助。我設法得到格式化的列表,所以製表符和雙空格都被刪除了,但我需要一些幫助。

回答

2

awk來救援:

$ awk 'last != $1; {last = $1}' 
domain1.foo. 3600 ... 
domain2.foo. 900 ... 
domain3.foo. 60 ... 
domain4.foo. 3600 ... 

這通過設置變量last從第一列的值。只有當第一列與last不同時,纔會打印當前行。

您還可以使用SED做到這一點,但你真的不應該:

sed ':s;N;/^\([^ ]*\) [^\n]*\n\1/{s/\n.*//;bs};P;D' 

上述作品讀出下一行到模式空間,並檢查是否在每行的第一列是相同。

如果它們相同,則刪除最後一行並且腳本再次跳轉到起始位置。

一旦兩列不同,首先被打印,然後被刪除,併爲第二行重複該腳本。

:s          # Label called `s' 
N          # Append next line to pattern space 
/^\([^ ]*\) [^\n]*\n\1/ {    # If the first columns are the same... 
    s/\n.*//       # Remove last line 
    b s        # Goto `s' 
}          # If the columns are not the same... 
P          # Print first line from pattern space 
D          # Delete the printed line 
0

andlcr's helpful awk answer是要走的路,尤其是考慮到它是便攜式(POSIX兼容),並與可變長度域名的作品。

在這個簡單的例子

  • 給出的固定數目的字符的。在該行的前綴,

  • 如果平臺有GNU實施uniq(驗證與 uniq --version

下面的工作太:

uniq -w 12 file