如何去除管道输出空白字符?解决grep提取标签重复问题
解决标签提取中的重复问题
嘿,这个问题我之前也碰到过!核心问题是你的grep命令把带末尾空格的标签和不带空格的标签当成了不同的匹配项,而直接用tr -d '[:space:]'会把所有空格都删掉,导致多个标签被错误拼接(比如:movie :read会变成:movie:read),完全不是我们想要的效果。
给你几个靠谱的解决方案,按需选择:
方法1:调整grep正则,只捕获标签本身
利用GNU grep支持的正向预查断言,匹配标签后面的空格/行尾,但不把空格包含到匹配结果里:
grep -o -e ":[a-z]*\(?=\s\|$\)" file.txt | sort | uniq
原理:\(?=\s\|$\)是零宽断言,它只会检查标签后面跟着空格或者行尾,但不会把空格纳入提取的内容,这样你得到的所有标签都是干净的:movie、:read,自然不会有重复。
方法2:用sed删除行尾空格后去重
如果你的grep不支持正则断言(比如BSD grep),可以先保留原来的grep匹配,再用sed把行尾的空格去掉:
grep -o -e ":[a-z]*\( \|$\)" file.txt | sed 's/ $//' | sort | uniq
这里sed 's/ $//'的作用是精准删除每行末尾的单个空格,不会影响标签内部(当然你的标签里也没有空格),处理后所有标签格式统一,再sort+uniq就能去重。
方法3:用awk直接提取合规标签
awk的字段分割特性天生适合处理这种带空格的场景,直接遍历每个字段,匹配符合:小写字母格式的标签并输出:
awk '{for(i=1;i<=NF;i++) if($i ~ /^:[a-z]*$/) print $i}' file.txt | sort | uniq
这种方法更灵活,哪怕一行里有多个标签(比如:movie :read),也能分别提取出来,而且自动去掉了字段前后的空格,根本不会出现重复问题。
拿你的测试输入举例,不管用哪种方法,最终输出都会是:
:movie :read
内容的提问来源于stack exchange,提问作者jerik
相关产品推荐
相关产品推荐

