【问题标题】:exchange two words using sed在 Linux 中使用 sed 交换两个单词
【发布时间】:2013-03-21 06:26:29
【问题描述】:

伙计们!我试图在一行中交换两个单词,但它不起作用。例如:“今天是我上大学的第一天”应该是“我今天是上大学的第一天”

这是我尝试过的:

sed 's/\([a-zA-z0-9]*\)\([a-zA-z0-9]*\)\([a-zA-z0-9]*\)/\3\2\1/' filename.txt

我做错了什么?

【问题讨论】:

  • 您应该使用另一个分隔符's#pat#repl#'。为了更清晰的命令。

标签: ubuntu sed


【解决方案1】:

试试这个:

sed -rn 's/(\w+\s)(\w+\s)(\w+\s)(.*)/\3\2\1\4/p' filename.txt

-n 禁止自动打印图案空间

-r 在脚本中使用扩展正则表达式

\s 表示空格

【讨论】:

  • 您需要使用 1 或更多而不是 0 或更多,否则如果句子以空格开头,它将匹配空字符串和第一个空格。
【解决方案2】:

我开始使用\s 来制作它,这意味着任何空格字符。
我用它来匹配[^\s]*的每个单词,它匹配所有内容,但不匹配空格。
我有\s* 用于匹配单词之间的空格。并且不要忘记在替换中重写一个空格。

看看这个例子:

sed 's#\([^ ]*\)\s+#\1 #'

(我使用# 而不是/

【讨论】:

  • 您需要使用 1 或更多而不是 0 或更多,否则如果句子以空格开头,您将匹配空字符串和第一个空格。
【解决方案3】:
sed -r 's/^(\w+)(\s+\w+\s+)(\w+)(.*)/\3\2\1\4/'

用你的例子:

kent$  echo "Today is my first day of university"|sed -r 's/^(\w+)(\s+\w+\s+)(\w+)(.*)/\3\2\1\4/'                                                                           
my is Today first day of university

对于您的问题,awk 更直接:

awk '{t=$1;$1=$3;$3=t}1'

相同的输入:

kent$  echo "Today is my first day of university"|awk '{t=$1;$1=$3;$3=t}1'                       
my is Today first day of university

【讨论】:

  • 可以通过删除 (.*)\4 来缩短 GNU sed 版本
【解决方案4】:

这可能对你有用(GNU sed):

sed -r 's/(\S+)\s+(\S+)\s+(\S+)/\3 \2 \1/' file 

【讨论】:

    【解决方案5】:

    你没有考虑空格。

    在单词之间使用 [ \t]+。

    【讨论】:

    • sed 's/([a-zA-z0-9]*)[\t]+([a-zA-z0-9]*)[\t]+([a- zA-z0-9]*)/\3\2\1/' filename.txt 它不工作! :(
    • + 需要转义:sed 's/\([a-zA-z0-9]*\)[ \t]\+\([a-zA-z0-9]*\)[ \t]\+\([a-zA-z0-9]*\)/\3\2\1/' filename.txt
    • 我想这会教我不要太快回答。最终的答案是您没有考虑原始搜索字符串中的空格。 \w+ 是我的想法。感谢您的更正。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 2019-09-18
    • 1970-01-01
    • 2019-09-15
    • 2019-03-07
    • 2012-04-23
    相关资源
    最近更新 更多