echo '60 test' | sed -r 's/(.*)\s+[^\s]+$/\1/'
结果:
60次测试
最后一列未剪切。
效果很好echo '60 home' | sed -r 's/(.*)\s+[^\s]+$/\1/'
结果:
60
为什么?
答案 0 :(得分:6)
[^\s]+
表示not backslash or s repeated 1 or more times
和test
包含s
,而home
不包含,因此后者与正则表达式匹配,而前者则不匹配。
您应该使用以下任意一种来匹配非空格:
$ echo '60 test' | sed -r 's/(.*)\s+\S+$/\1/'
60
$ echo '60 test' | sed -r 's/(.*)\s+[^[:space:]]+$/\1/'
60
正如@potong在评论中建议的那样,要删除带有sed的最后一列,您真正需要的是:
sed -E 's/\s+\S+$//'
我从-r
切换到-E
是因为-r
仅在GNU或OSX / BSD时被GNU sed,所以通常使用BUT OSX是更好的选择/ BSD sed无法识别-E
或\s
,因此在这种情况下,从\S
更改为-r
并不能使脚本更具可移植性,您必须改用它:
-E
然后完全可移植到所有POSIX sed中:
sed -E 's/[[:space:]]+[^[:space:]]+//'
否则,如果始终有2个或更多字段,则其行为将相同:
sed 's/[[:space:]]\{1,\}[^[:space:]]\{1,\}//'
答案 1 :(得分:1)
如果您只是在空格之前打印字符串的第一部分而不进行任何其他修改,则可以简单地使用cut
echo '60 test' | cut -d' ' -f1
60
在其中定义定界符(-d)和要选择的字段(-f)。
无需使用sed
进行复杂的解决方案并进行一些替换操作。
使用awk
,您还可以打印第一个字段:
echo '60 test' | awk '{print $1}'
60
或在perl模式下通过grep
将\s
考虑在内
echo '60 test' | grep -oP '^.*?(?=\s)'
60