使用sed反转输入顺序

use*_*254 5 unix bash command-line sed

我有一个文件,我们称之为'a.txt',这个文件包含以下文本行

do to what
Run Code Online (Sandbox Code Playgroud)

我想知道SED命令是什么来反转这个文本的顺序使它看起来像

what to do
Run Code Online (Sandbox Code Playgroud)

我必须做某种追加吗?就像将'do'追加到'to'所以它看起来像

to ++ do(使用++只是为了清楚)

Ber*_*ard 8

我知道tac可以做一些相关的事情

$ cat file
 do to what
$ tac -s' ' file

what to do  $
Run Code Online (Sandbox Code Playgroud)

-s定义的分隔符,默认情况下一个换行符.


F. *_*uri 2

答案

由于这个问题被标记为,我的第一个答案是:

首先(当包含时_,使用仲裁来标记查看的空间:a.txtdo to what

sed -e '
    :a;
    s/\([^_]*\) \([^ ]*\)/\2_\1/;
    ta;
    y/_/ /;
   ' a.txt
what to do
Run Code Online (Sandbox Code Playgroud)

比,当a.txt包含do to to what

sed -e '
    :a;
    s/^\(\|.* \)\([^+ ]\+\) \2\([+]*\)\(\| .*\)$/\1\2\3+\4/g;
    ta;
    :b;
    s/\([^_]*\) \([^ ]*\)/\2_\1/;
    tb;
    y/_/ /;
   ' <<<'do to to to what'
what to++ do
Run Code Online (Sandbox Code Playgroud)

+每个抑制的重复单词都有一个:

sed -e ':a;s/^\(\|.* \)\([^+ ]\+\) \2\([+]*\)\(\| .*\)$/\1\2\3+\4/g;ta;
        :b;s/\([^_]*\) \([^ ]*\)/\2_\1/;tb;
        y/_/ /;' <<<'do do to what what what what'
what+++ to do+
Run Code Online (Sandbox Code Playgroud)

答案

但由于有很多人在寻找简单的解决方案,因此有一个简单的方法:

xargs < <(uniq <(tac <(tr \  \\n <<<'do do to what what what what')))
what to do
Run Code Online (Sandbox Code Playgroud)

这可以写成:

tr \  \\n <<<'do do to what what what what' | tac | uniq | xargs 
what to do
Run Code Online (Sandbox Code Playgroud)

甚至使用一些脚本:

revcnt () { 
    local wrd cnt plut out="";
    while read cnt wrd; do
        printf -v plus %$((cnt-1))s;
        out+=$wrd${plus// /+}\ ;
    done < <(uniq -c <(tac <(tr \  \\n )));
    echo $out
}
Run Code Online (Sandbox Code Playgroud)

会做:

revcnt <<<'do do to what what what what' 
what+++ to do+
Run Code Online (Sandbox Code Playgroud)

或者作为纯粹的

revcnt() { 
    local out i;
    for ((i=$#; i>0; i--))
    do
        [[ $out =~ ${!i}[+]*$ ]] && out+=+ || out+=\ ${!i};
    done;
    echo $out
}
Run Code Online (Sandbox Code Playgroud)

其中提交的字符串必须作为参数提交:

revcnt do do to what what what what
what+++ to do+
Run Code Online (Sandbox Code Playgroud)

或者,如果需要处理标准输入(或来自文件):

revcnt() { 
    local out i arr;
    while read -a arr; do
        out=""
        for ((i=${#arr[@]}; i--; 1))
        do
            [[ $out =~ ${arr[i]}[+]*$ ]] && out+=+ || out+=\ ${arr[i]};
        done;
        echo $out;
    done
}
Run Code Online (Sandbox Code Playgroud)

所以你可以处理多行:

revcnt <<eof
do to what
do to to to what
do do to what what what what
eof
what to do
what to++ do
what+++ to do+
Run Code Online (Sandbox Code Playgroud)