2013-05-14 105 views
0

我有一個需要一些操作的大型數據庫文件。基本上我需要避免重複的字段由'|'分隔爲:awk - 僅打印第一行重複項和它下面的行

-- TITLE1 | TITLE2 |T3 |TITLE4|TITLE5 
----------|----------|-----|------|--------------- 
-- 
DATA1 | SAME  |  |  | blah blah 
ELIGIBLE | x1 
DATA1 | SAME  |  | blah | blah 
ELIGIBLE | x2 
DATA1 | SAME  |  | blah | blah blah 
ELIGIBLE | x2 
DATA2 | SAME  |  |  | blah blah 
ELIGIBLE | y1 
DATA2 | SAME  |  | blah | blah 
ELIGIBLE | y2 
DATA2 | SAME  |  | blah | blah blah blah blah 
ELIGIBLE | y2 
DATA3 | SAME  |  |  | blah blah 
ELIGIBLE | z1 
DATA3 | SAME  |  | blah | blah 
ELIGIBLE | z2 
DATA3 | SAME  |  | blah | blah blah blah blah 
ELIGIBLE | z2 

我使用的代碼是

BEGIN{ FS = "|" } 
{ 
count[$1]++; 
if (count[$1] == 1) 
first [$1] = $0; 
if (count[$1] > 1) 
print first[$1] 
NR==1; 
} 

但它給我的輸出:

-- TITLE1 | TITLE2 |T3 |TITLE4|TITLE5 
----------|----------|-----|------|--------------- 
-- 
DATA1 | SAME  |  |  | blah blah 
ELIGIBLE | x1 
DATA2 | SAME  |  |  | blah blah 
DATA3 | SAME  |  |  | blah blah 

我寧願像這樣的輸出:

-- TITLE1 | TITLE2 |T3 |TITLE4|TITLE5 
----------|----------|-----|------|--------------- 
-- 
DATA1 | SAME  |  |  | blah blah 
ELIGIBLE | x1 
DATA2 | SAME  |  |  | blah blah 
ELIGIBLE | y1 
DATA3 | SAME  |  |  | blah blah 
ELIGIBLE | z1 

我並不關心標題欄,但n通過它來顯示數據。對不起,業餘解釋,但任何解決方案的幫助,將不勝感激。我是新手,當涉及到Linux命令行腳本,所以如果任何人也可以解釋爲什麼我的答案是錯誤的,我將不勝感激。我不侷限於awk,並且可以使用任何命令解決方案。我只想用awk嘗試解決方案。

+0

所以,你需要保留的數據的第一行與給定TITLE1扔掉剩下的,即使他們有不同的TITLE5的等? – 2013-05-14 15:14:19

+0

是正確的,並保留符合條件的行。 – 2013-05-14 15:40:03

回答

0

你可以試試這個:

awk -F\| '(printed!=0 && /ELIGIBLE/) {print; printed=0;} (!seen[$1] && $1 !~ /ELIGIBLE/) { print; printed = 1; seen[$1] = 1; }' 

雖然有幾乎可以肯定是更好的方式。

ETA:在網絡上有一個很好的Awk教程here和其他幾個人,以及一些好書。但基本上,awk程序是一系列模式和代碼塊,以便在每個與該模式匹配的記錄(缺省情況下爲行)上運行。

awk '/foo/   { do this for lines that contain "foo" anywhere } 
    ($1 == "bar") { do this for lines whose first field is exactly "bar' } 
    ($NF ~ /baz/) { do this for lines whose last field contains "baz" } 
    (NF == 1)  { do this for lines with exactly one field } 
    (NR == 10)  { do this only on the 10th line }' 

如果沒有圖案,塊會在每一行上運行。

awk '{print $NF}' # print the last field of every line 

如果沒有塊,只是一個圖案,然後匹配的行被打印不變:

awk '/foo/'  # same as grep foo 

標記的任何輸入被處理之前開始運行A嵌段;在處理完所有輸入後運行標有END的塊。

awk 'BEGIN { t = 0 } {t += $NF} END { print t }' # print total of last column 

但實際上未初始化變量視爲算術0,這樣你就可以跳過初始化:

awk '{t += $NF} END {print t}' 

AWK的一些版本需要模式/塊對之間用分號;或換行

+0

該解決方案非常完美,非常感謝!你能解釋一下如何使用awk排除/包含文本。對不起,我正在學習,只用它來進行字段匹配。 – 2013-05-14 17:23:14

+0

如果這回答了你的問題,你應該接受答案... – 2013-05-14 23:53:48

0

這條線適用於你給定的例子。 (數據被排序,在線數據,在線符合條件...)如果格式改變,不能保證爲真實數據工作。你必須自己測試它。

標題/標題被跳過。

awk -F'|' '!(NR%2){next}$1 in a{next}{print;a[$1];getline;print}' file 

嘗試:

kent$ awk -F'|' '!(NR%2){next}$1 in a{next}{print;a[$1];getline;print}' file 
DATA1 | SAME  |  |  | blah blah 
ELIGIBLE | x1 
DATA2 | SAME  |  |  | blah blah 
ELIGIBLE | y1 
DATA3 | SAME  |  |  | blah blah 
ELIGIBLE | z1