我正在尝试使用sed来切换句子中第一个和最后一个单词的顺序,因为我不认为我理解在这种情况下“贪婪”的正则表达式是多少。我只是因为三个字的句子而悲惨地失败了。
$ echo hello world mike | sed 's/\([a-z]*\).* \([a-z]*\).*/\2 \1/'
mike hello
为什么输出不是“世界你好迈克”? 一些可能有用的额外信息。
\ 1 \ 2是第一个和第二个正则表达式匹配
我关注的是tutorial here。
我的最终目标是切换句子中第一个和最后一个单词的顺序,而不管其中有多少个单词。
答案 0 :(得分:7)
您没有将hello
部分包含为您的某个捕获组,因此无法获得输出。尝试:
$ sed -E 's/([a-z]+) (.+) ([a-z]+)/\3 \2 \1/' <<< "hello world mike"
mike world hello
$ sed -E 's/([a-z]+) (.+) ([a-z]+)/\3 \2 \1/' <<< "hello world foo bar baz mike"
mike world foo bar baz hello
(注意:我也删除了您的useless use of echo。)
您也可以将[a-z]
替换为[[:alpha:]]
来处理大写字母:
$ sed -E 's/([[:alpha:]]+) (.+) ([[:alpha:]]+)/\3 \2 \1/' <<< "Hello world Mike"
Mike world Hello
答案 1 :(得分:2)
其他awk
版本
echo hello world mike | awk '{s=$1;$1=$NF;$NF=s}1'
mike world hello
只需交换最后一次和第一次提交的文件即可。
答案 2 :(得分:2)
$ echo "hello world mike" | sed -r 's/([^ ]+)(.* )([^ ]+)/\3\2\1/'
mike world hello
$ echo "this is a simple sentence" | sed -r 's/([^ ]+)(.+ )([^ ]+)/\3\2\1/'
sentence is a simple this
或仅支持BRE的老式seds,而不是ERE:
$ echo "hello world mike" | sed 's/\([^ ]*\)\(.* \)\([^ ]*\)/\3\2\1/'
mike world hello
$ echo "this is a simple sentence" | sed 's/\([^ ]*\)\(.* \)\([^ ]*\)/\3\2\1/'
sentence is a simple this
答案 3 :(得分:1)
使用awk:
$ echo 'hello world mike' | awk '{v1=$1;v2=$NF;$1=$NF="";print v2, $0, v1}'
mike world hello
答案 4 :(得分:1)
你要求交换行上的第一个和最后一个单词 - 所以你需要确保你捕获那些(而不是第一个和第二个单词,正如上面的许多答案所做的那样)。
echo "hello cruel and unkind world" | sed 's/^\([^ ]*\) \(.*\) \([^ ]*\)$/\3 \2 \1/'
将导致
world cruel and unkind hello
以下是它的工作原理:
^\([^ ]*\) - starting at the beginning of the line (^), find as many non-space characters as you can (stops at first space)
note - depending on the flavor of sed you use, there are special symbols to map "a non whitespace, e.g. \S
- the next space is matched but not captured
\(.*\) - capture "everything" after this, until...
\([^ ]*\)$ - a space followed by all non-space characters followed by the end of string
当你以相反的顺序输出三个捕获组时,中间有一个空格,你就得到了你所要求的。
答案 5 :(得分:1)
带字边界的sed命令:
sed 's/\([A-Za-z]\+\)\(.\+\)\b\([A-Za-z]\+\)/\3\2\1/'
或在扩展模式下:
sed -r 's/([A-Za-z]+)(.+)\b([A-Za-z]+)/\3\2\1/'
答案 6 :(得分:0)
我会使用其他方法,例如更强大的语言的split()
,但对于sed,您必须对两个边词之间的所有内容进行分组:
echo hello world mike | sed 's/\([a-z]*\)\(.*\) \([a-z]*\).*/\3\2 \1/'
它产生:
mike world hello