如何使用sed / awk删除多个模式计数的单词

时间:2012-06-16 21:01:38

标签: 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

感谢

4 个答案:

答案 0 :(得分: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选项只会更改需要转义的字符:如果不将()-{}|全部\视为常规字符,除非您使用(转义它们。相反,要将文字 -rsed选项匹配,您需要将其转义。

P.P.S。这是man sed的{​​{3}}。 {{1}}也是你的朋友。 如果您还有其他问题,请与我们联系。

答案 1 :(得分:0)

您可以尝试使用perl而不是sed或awk:

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

答案 2 :(得分:0)

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

这应该适用于更多情况:

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

答案 3 :(得分:0)

这可能对您有用:

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