如何使用 sed 和多个分隔符交换两个单词?

如何使用 sed 和多个分隔符交换两个单词?

单词中只接受字母,任何其他字符都是分隔符。我想把第一个词和第三个词交换。

sed -E 's/([A-Za-z]+) [^A-Za-z] ([A-Za-z]+) [^A-Za-z] ([A-Za-z]+)/\3 \2 \1/' filename

我写了这个但不能正常工作

例子:

I 4want5to%change

我想将这个字符串更改为:

to 4want5I%change

任何想法?

答案1

使用字符类[[:alpha:]]来匹配大写和小写,并使用否定[^[:alpha:]]来匹配所有其他字符:

sed -r 's/^([^[:alpha:]]*)([[:alpha:]]+)([^[:alpha:]]+[[:alpha:]]+[^[:alpha:]]+)([[:alpha:]]+)([^[:alpha:]]*)/\1\4\3\2\5/' file.txt

例子:

$ sed -r 's/^([^[:alpha:]]*)([[:alpha:]]+)([^[:alpha:]]+[[:alpha:]]+[^[:alpha:]]+)([[:alpha:]]+)([^[:alpha:]]*)/\1\4\3\2\5/' <<<'I 4want5to%change'
to 4want5I%change

$ sed -r 's/^([^[:alpha:]]*)([[:alpha:]]+)([^[:alpha:]]+[[:alpha:]]+[^[:alpha:]]+)([[:alpha:]]+)([^[:alpha:]]*)/\1\4\3\2\5/' <<<'4I 4want5to%change'
4to 4want5I%change

$ sed -r 's/^([^[:alpha:]]*)([[:alpha:]]+)([^[:alpha:]]+[[:alpha:]]+[^[:alpha:]]+)([[:alpha:]]+)([^[:alpha:]]*)/\1\4\3\2\5/' <<<'Spring&summer^winter'
winter&summer^Spring

答案2

去掉空格,并修复反向引用以保留分隔符。另外,由于您有一个分隔符“ <space>4”,因此显然需要允许连续多个“分隔符”字符作为分隔符。

您应该指定它位于行的开头。

所以而不是:

sed -E 's/([A-Za-z]+) [^A-Za-z] ([A-Za-z]+) [^A-Za-z] ([A-Za-z]+)/\3 \2 \1/' filename

使用:

sed -E 's/^([A-Za-z]+)([^A-Za-z]+[A-Za-z]+[^A-Za-z]+)([A-Za-z]+)/\3\2\1/' filename

答案3

如果您还没有使用 sed,这对 perl 来说是一份不错的工作:在这里我还提供了指定您想要交换哪些单词的功能

如果“文件”包含

I 4want5to%change
#One two three four
Spring&summer^winter

然后这个命令

$ perl -lnse '
    BEGIN {
        $i = ($first - 1) * 2;
        $j = ($second - 1) * 2;
    }
    @tokens = /([[:alpha:]]*)([^[:alpha:]]*)/g;
    ($tokens[$i], $tokens[$j]) = ($tokens[$j], $tokens[$i]);
    print join "", @tokens;
' -- -first=1 -second=3 file

输出

to 4want5I%change
two#One  three four
winter&summer^Spring

相关内容