2012-06-16 81 views
1

我有一個字符串記錄文件,其中一個字段(用「,」分隔)可以在其中包含一個或多個「 - 」。如何使用sed/awk刪除具有多個模式計數的單詞

目標是刪除字段值,如果它包含兩個以上的「 - 」。

我試圖挽回我的SED/AWK的過去的知識,但不能太大進展

==========

info,whitepaper,Data-Centers,yes-the-6-top-problems-in-your-data-center-lane 

info,whitepaper,Data-Centers,the-evolution-center 

info,whitepaper,Data-Centers,the-evolution-of-lan-technology-lanner 

====== ====

預期的結果:

info,whitepaper,Data-Centers 

info,whitepaper,Data-Centers,the-evolution-center 

info,whitepaper,Data-Centers 

感謝

回答

1

嘗試

sed -r 's/(^|,)([^,-]+-){3,}[^,]+(,|$)/\3/g' 

,或者如果你到斜線

sed 's/\(^\|,\)\([^,-]\+-\)\{3,\}[^,]\+\(,\|$\)/\3/g' 

說明:

我使用的是最基本的sed命令:替換。語法是:s/pattern/replacement/flags

這裏pattern(^|,)([^,-]+-){3,}[^,]+(,|$)replacement\3flagsg

g標誌意味着全局替換(所有匹配的部分都被替換,不僅是第一行)。

pattern

  • 括號()創建組。有點像數學。他們還允許稍後參考一個具有數字的組。
  • ^$表示字符串的開始和結束。
  • |表示「或」,所以(^|,)的意思是「逗號或字符串的開始」。
  • 方括號[]表示一個字符類,^裏面的意思是否定。所以[^,-]的意思是「除逗號或連字符之外的任何東西」。通常連字符在字符類中具有特殊含義:[a-z]表示全部小寫字母。但這裏只是一個連字符,因爲它不在中間。
  • +表達後意思是「匹配1次或更多次」(如*表示匹配0次或更多次)。
  • {N}裝置「匹配它恰好N次。{N,M}是‘從NM倍’。{3,}指‘三次或更多個’。+相當於{1,}

就是這樣。 replacement只是\3。這指的是()中的第三組,在這種情況下爲(,|$)。這將是替代後唯一剩下的東西。

P.S. -r選項只是更改需要轉義的字符:沒有它,()-{}|的所有字符都將被視爲常規字符,除非您使用\轉義字符。相反,要匹配文字(-r選項,您需要將其轉義。

P.P.S. sed這是referenceman sed也是你的朋友。 如果您還有其他問題,請告訴我。

+0

不,刪除這些行,OP想要刪除這些字段。 –

+0

感謝您的快速響應,只是意識到,該列正在研究的模式,可以是任何列,而不是專門第4列,如上面 /yes /丹尼斯指出的那樣,我正在刪除字段不是記錄,加上刪除任何包含2個以上「 - 」模式的列 –

+0

對不起,大家,請參閱編輯答案。 –

0

你可以嘗試的Perl,而不是awk或者sed:

perl -F, -lane 'print join ",", grep { !/-.*-.*-/ } @F' < file.txt 
+0

works/thnx-期待着花我的星期天與Sed和Awk,現在也會邀請Perl :) –

0
sed 's/\(^\|,\)\([^,]*-\)\{3\}[^,]*\(,\|$\)//g' 

這應該在更多的情況下工作:

sed 's/,$/\n/g;s/\(^\|,\|\n\)\([^,\n]*-\)\{3\}[^,\n]*\(,\|\n\|$\)/\3/g;s/,$//;s/\n/,/g' 
+0

如果包含模式的字段未知,這將如何工作 –

+0

@JungleBoy:這不是特定於某個特定領域的。 「3」重複前面一組圓括號中的模式,並且與下面的[[,]] *一起將匹配任意數量的連字符,只要至少有3個。總體匹配將匹配任何字段(這是'\(^ \ |,\)'和'\(,\ | $ \)'做的)。 –

+0

thnx澄清/陷入「3」/欣賞努力 –

0

這可能會爲你工作:

sed 's/,\{,1\}[^,-]*\(-[^,]*\)\{3,\}//g file 
相關問題