如何在sed中仅保留第一个匹配到的连字符?
问题原因
你当前的命令逻辑是保留所有大写字母、数字、连字符三类字符,自动删除其余内容,所以原字符串中4991之后的三个分隔小写单词的连字符也被保留,才会得到带多余后缀连字符的结果。
解决方案
方案1:精准匹配提取(最稳定,推荐)
直接用sed捕获组匹配你需要的「大写字母+连字符+数字」片段,忽略其余所有内容:
echo home/JOHNSMITH-4991-common-task-list | sed -E 's/.*\/([A-Z]+-[0-9]+).*/\1/'
原理:
-E开启扩展正则,不用额外转义括号.*\/匹配路径前缀到最后一个/为止的所有内容([A-Z]+-[0-9]+)捕获你需要的「连续大写字母+单个连字符+连续数字」片段.*匹配后面所有不需要的内容- 最终输出第一个捕获组
\1的内容,就是你要的JOHNSMITH-4991
方案2:基于现有逻辑优化
如果你要保留原来的字符过滤逻辑,只需加一步替换,删除数字后面的所有内容即可:
echo home/JOHNSMITH-4991-common-task-list | sed 's/[^A-Z0-9-]//g; s/\([0-9]\)-.*/\1/'
原理:第一步过滤后得到JOHNSMITH-4991---,第二步替换匹配「数字后跟连字符及后续所有内容」,只保留前面的数字,就能去掉多余的连字符。
方案3:用grep直接匹配目标片段
更简单的方式是用grep的-o参数只输出匹配到的目标片段:
echo home/JOHNSMITH-4991-common-task-list | grep -oE '[A-Z]+-[0-9]+'
内容的提问来源于stack exchange,提问作者Alan Smith
相关产品推荐
相关产品推荐

