一本介绍 sed 命令的 Linux 教科书给出了以下示例:
sed -e 's/\(<[^ ]*>\)\([ ]*\)\(<[^ ]*>\)/\3\2\1/g'
GNU Linux is cool
Linux GNU cool is
但是当我输入与 about 完全相同的命令时,它显示:
sed -e 's/\(<[^ ]*>\)\([ ]*\)\(<[^ ]*>\)/\3\2\1/g'
GNU Linux is cool
GNU Linux is cool
有人能帮我解决这个问题吗?我正在使用 Ubuntu 12.04LTS。非常感谢。
答案1
这可能只是论坛格式的问题,但<
和>
大概是词锚因此需要反斜杠转义\<
和\>
sed -e 's/\(\<[^ ]*\>\)\([ ]*\)\(\<[^ ]*\>\)/\3\2\1/g'
IE
echo 'GNU Linux is cool'| sed -e 's/\(\<[^ ]*\>\)\([ ]*\)\(\<[^ ]*\>\)/\3\2\1/g'
Linux GNU cool is
然而,像之前的发帖者一样,我也建议使用 GNU-r
扩展形式来减少转义的次数
sed -re 's/(\<[^ ]*\>)([ ]*)(\<[^ ]*\>)/\3\2\1/g'
*
如果将“(零个或多个)”改为+
“(一个或多个)”,那么“锚点”这个词似乎就没有必要了。
echo 'GNU Linux is cool'| sed -re 's/([^ ]+)([ ]+)([^ ]+)/\3\2\1/g'
Linux GNU cool is
答案2
嗯,我不知道。这里有几个问题:
- 您需要启用扩展模式才能进行这些比赛(
-r
) - 您不需要启用脚本模式(
-e
),但这并不是错误 - 有很多括号转义在语法上是不正确的(你需要那些来匹配)
- 我根本搞不懂尖括号是干什么用的。所以我删除了它们。
/g
全局模式会破坏它,因为它会交换最后三个单词并破坏空格。如果你愿意,可以尝试一下。
下面是它的工作原理:
$ echo "GNU Linux is cool" | sed -r "s/([^ ]*)([ ]*)([^ ]*)/\3\2\1/"
Linux GNU is cool
一个更好/更短/更易读的方法是删除第二组,只使用文字空格。像这样:
$ echo "GNU Linux is cool" | sed -r "s/([^ ]*) ([^ ]*)/\2 \1/"
Linux GNU is cool