理解 sed 表达式以将每行的最后一个单词替换为第一个单词

L.R*_*ert 4 command-line sed text-processing

我必须用第一个词替换每一行的最后一个词。代码是:

$ sed "s/\(^a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)/\1\2\1\g". 
Run Code Online (Sandbox Code Playgroud)

这部分我\(^a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)特别不明白\(.*\)

Zan*_*nna 10

纠正基本语法错误后,您有:

sed "s/\(^[a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)/\1\2\1/g"
Run Code Online (Sandbox Code Playgroud)
  • s/old/new/替换oldnew
  • \(^[a-z,0-9]*\)在行首(^是行首)保存任意数量的小写字母或数字以备后用(稍后参考\1
  • \(.*\)保存任意数量的任意字符以备后用(参考为\2
  • \([a-z,0-9]*$\)在行尾(即行$尾)保存任意数量的小写字母或数字以备后用(参考为\3
  • \1\2\1 打印第一个图案,然后是第二个,然后再次打印第一个
  • g这在这个表达中是不合适的。这意味着对同一行上的多个匹配进行操作,但我们的表达式必须读取整行,因此g没有意义,应该省略。

这还是不行,因为正则表达式是贪心的,所以中间\(.*\)匹配第一个单词之后的所有内容,导致第一个单词在行尾重印,没有替换任何内容。

你可以修复它(也添加I不区分大小写的搜索):

sed "s/\(^[a-z,0-9]*\) \(.*\) \([a-z,0-9]*$\)/\1 \2 \1/I"
Run Code Online (Sandbox Code Playgroud)

如果您想包含字母和数字以外的其他字符:

sed -r 's/^([^ ]+) (.*) ([^ ]+)$/\1 \2 \1/'
Run Code Online (Sandbox Code Playgroud)
  • -r 使用 ERE(使用所有这些反斜杠保存)
  • [^ ]+ 除空格外的任何字符中的至少一个