如何交换行中首尾数字?sed命令匹配行尾多位数异常排查
问题分析与解决:Sed交换行首行尾数字串只匹配单个数字的问题
嘿,我完全懂你现在的困惑——明明想把行首的1234和行尾的89交换位置,结果sed只抓了行尾的9,咱们一步步拆解问题出在哪:
问题根源:正则表达式的语法错误
你写的正则里,第三组的\([0-9]*\{1,\}\)是核心问题:
- 在sed默认使用的基础正则表达式中,
*是「匹配0次或多次」的量词,\{1,\}是「匹配至少1次」的量词。把两个量词直接连在一起用是错误的语法,它根本达不到「匹配至少1个连续数字」的效果。 - 更关键的是,这个错误的正则实际等价于
[0-9]*(匹配0或多个数字),再加上.*是贪婪匹配(会尽可能吃掉最多的字符),所以.*会把行尾的8也包含进去,只给第三组留下最少能满足条件的单个数字9。
修正后的命令
把第三组的正则改成正确的「匹配至少1个连续数字」的写法\([0-9]\{1,\}\),完整命令如下:
echo 1234jj h777 jj89 | sed 's/^\([0-9]\{1,\}\)\(.*\)\([0-9]\{1,\}\)$/\3\2\1/'
执行后就能得到预期输出:89jj h777 jj1234
更简洁的扩展正则写法
如果你觉得转义括号和量词太繁琐,可以用-E参数启用扩展正则表达式,语法会更直观:
echo 1234jj h777 jj89 | sed -E 's/^([0-9]+)(.*)([0-9]+)$/\3\2\1/'
这里的+就是「匹配至少1次」的意思,不需要额外转义,可读性更强。
补充说明:贪婪匹配的影响
为什么修正后就能匹配完整的89?因为.*虽然还是贪婪,但第三组的正则[0-9]\{1,\}要求匹配连续的数字串,.*会在碰到行尾的连续数字时停下来,把完整的89留给第三组,而不是只留单个数字。
内容的提问来源于stack exchange,提问作者ramya sukumar
相关产品推荐
相关产品推荐

