1

我有一个字符串记录文件,其中一个字段 - 由“,”分隔 - 可以在其中包含一个或多个“-”。

目标是删除包含两个以上“-”的字段值。

我正在努力恢复我过去对 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

4 回答 4

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。_ ()在这种情况下,这是指第三组(,|$)。这将是替换后唯一剩下的东西。

PS该-r选项只会更改需要转义的字符:没有它,所有字符都将()-{}|被视为常规字符,除非您使用\. 相反,要将文字 (-r选项匹配,您需要对其进行转义。

PPS这是sed. man sed也是你的朋友。如果您还有其他问题,请告诉我。

于 2012-06-16T21:12:29.733 回答
0

这可能对您有用:

sed 's/,\{,1\}[^,-]*\(-[^,]*\)\{3,\}//g file
于 2012-06-17T02:12:56.293 回答
0

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

perl -F, -lane 'print join ",", grep { !/-.*-.*-/ } @F' < file.txt
于 2012-06-16T21:21:17.480 回答
0
sed 's/\(^\|,\)\([^,]*-\)\{3\}[^,]*\(,\|$\)//g'

这应该适用于更多情况:

sed 's/,$/\n/g;s/\(^\|,\|\n\)\([^,\n]*-\)\{3\}[^,\n]*\(,\|\n\|$\)/\3/g;s/,$//;s/\n/,/g'
于 2012-06-16T21:23:55.900 回答