我有一个字符串记录文件,其中一个字段--由",“分隔--可以在其中包含一个或多个"-”。
目标是如果字段值包含两个以上的"-“,则删除它。
我正在努力恢复我过去对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谢谢
发布于 2012-06-16 21:12:29
试一试
sed -r 's/(^|,)([^,-]+-){3,}[^,]+(,|$)/\3/g'或者如果你喜欢斜杠
sed 's/\(^\|,\)\([^,-]\+-\)\{3,\}[^,]\+\(,\|$\)/\3/g'解释:
我使用的是最基本的sed命令:替换。语法是:s/pattern/replacement/flags。
这里pattern是(^|,)([^,-]+-){3,}[^,]+(,|$),replacement是\3,flags是g。
g标志意味着全局替换(所有匹配的部件都被替换,而不仅仅是行中的第一个)。
在pattern中
()创建一个组。有点像数学。它们还允许指后面有一个数字的组。^和$表示字符串的开始和结束。|的意思是“或”,所以(^|,)的意思是“逗号或字符串的开头”。[]表示一个字符类,^在里面表示否定。所以[^,-]的意思是“除了逗号或连字符以外的任何东西”。通常情况下,连字符在字符类中有一个特殊的含义:[a-z]表示所有小写字母。但这里只是一个连字符,因为它不在中间。+表示“匹配它1次或更多次”(就像*的意思是匹配它0次或更多次)。{N}的意思是“完全匹配N时间。{N,M}是”从N到M times“。{3,}的意思是”三次或更多次“。+等同于{1,}。所以就是这样了。replacement只是\3。这指的是()中的第三个组,在本例中是(,|$)。这将是换人后剩下的唯一的东西。
P.S. -r选项只是改变了需要转义的字符:没有它,所有的()-{}|都被当作常规字符处理,除非您用\转义它们。相反,要将文本(与-r选项匹配,则需要将其转义。
这是参考文献给sed的。man sed也是你的朋友。如果你还有其他问题,请告诉我。
发布于 2012-06-16 21:21:17
您可以尝试perl,而不是sed或awk:
perl -F, -lane 'print join ",", grep { !/-.*-.*-/ } @F' < file.txt发布于 2012-06-16 21:23:55
sed 's/\(^\|,\)\([^,]*-\)\{3\}[^,]*\(,\|$\)//g'在更多的情况下,这应该是可行的:
sed 's/,$/\n/g;s/\(^\|,\|\n\)\([^,\n]*-\)\{3\}[^,\n]*\(,\|\n\|$\)/\3/g;s/,$//;s/\n/,/g'https://stackoverflow.com/questions/11067008
复制相似问题