我有一个字符串记录文件,其中一个字段 - 由“,”分隔 - 可以在其中包含一个或多个“ - ”。
目标是删除字段值,如果它包含两个以上的“ - ”。
我正在尝试收回我过去对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
感谢
答案 0 :(得分:1)
尝试
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
次“。{3,}
表示”三个时间或更长时间“。+
相当于{1,}
。就是这样。 replacement
只是\3
。这指的是()
中的第三个群组,在本例中为(,|$)
。这将是替换后唯一剩下的东西。
P.S。 -r
选项只会更改需要转义的字符:如果不将()-{}|
全部\
视为常规字符,除非您使用(
转义它们。相反,要将文字 -r
与sed
选项匹配,您需要将其转义。
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