这个 sed 表达式有什么问题?

这个 sed 表达式有什么问题?
$ echo "104_Fri" | sed 's/^\([0-9]+\)_\([A-Za-z]+\)$/\1;\2/'
104_Fri

我想匹配开头的数字和结尾的字母 - 每个都作为一个组。之后我想输出第一组、分号,然后输出第二组。

我希望这个表达式能够产生:

104;Fri

为什么这不起作用?

答案1

反斜杠+

$ echo "104_Fri" | sed 's/^\([0-9]\+\)_\([A-Za-z]\+\)$/\1;\2/'
104;Fri

注意+不是标准的基本正则表达式元字符,因此即使使用反斜杠也不具有可移植行为sed

您应该使用sed -rsed -E启用扩展正则表达式相反,您不需要反斜杠任何这些字符。这些选项也是非标准的,但至少如果它们不受支持,您会收到错误,而不是神秘的故障。这些选项支持GNUsed以及所有主要的 BSD 衍生品(自由BSD,开放BSD,网络BSD,操作系统),但在许多商业 Unix 版本中没有。

如果您需要真正可移植的扩展正则表达式,请使用awk,总是使用它们

答案2

您也必须转义加号+

$ echo "104_Fri" | sed 's/^\([0-9]\+\)_\([A-Za-z]\+\)$/\1;\2/'
104;Fri

答案3

添加用于扩展正则表达式的选项;-),并且对活动内容-r的需求减少。\

$回声“104_Fri”| sed -re 's/^([0-9]+)_([A-Za-z]+)$/\1;\2/'
104;星期五

在编写 Q 时,(无背景数据)分割任务可以通过其他几种更简单的方式完成:

$回声“104_Fri”| tr '_' ';'
104;星期五

$回声“104_Fri”| sed 's/_/;/'
104;星期五

...仅举两个例子。

答案4

我建议使用 Perl,因为它预装在大多数 Unix 系统上:

$ echo '104_Fri' | perl -p -e 's/^([0-9]+)_([A-Za-z]+)$/$1;$2/'

您可以进一步简化:

$ echo '104_Fri' | perl -p -e 's/^(\d+)_([a-z]+)$/$1;$2/i'

笔记:如果您的输入确实像问题中一样简单,则简单的tr即可:

$ echo '104_Fri' | tr '_' ';'

或者使用 Perl:

$ echo '104_Fri' | perl -p -e 's/_/;/'

相关内容