7

私はファイルを持っています。それを「a.txt」と呼びましょう。このファイルには次のテキスト行が含まれています

do to what

このテキストの順序を逆にして次のように表示する SED コマンドが何であるか疑問に思っています

what to do

ある種の追加を行う必要がありますか? 「to」に「do」を追加すると、次のようになります

to ++ do (明確にするために ++ を使用)

4

6 に答える 6

8

私はtac関連する何かをすることができることを知っています

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

what to do  $

ここで、-sは区切り文字を定義します。これはデフォルトでは改行です。

于 2012-10-28T11:51:25.863 に答える
3

私はawkこれを行うために使用します:

awk '{ for (i=NF; i>=1; i--) printf (i!=1) ? $i OFS : $i "\n" }' file.txt

結果:

what to do

編集

ファイルを「その場で」変更するためにワンライナーが必要な場合は、次を試してください。

{ rm file.txt && awk '{ for (i=NF; i>=1; i--) printf (i!=1) ? $i OFS : $i "\n" }' > file.txt; } < file.txt
于 2012-10-28T11:50:59.983 に答える
2

これはうまくいくかもしれません(GNU sed):

sed -r 'G;:a;s/^\n//;t;s/^(\S+|\s+)(.*)\n/\2\n\1/;ta' file

説明:

  • Gパターンスペースの最後に改行を追加 (PS)
  • :aループネームスペース
  • s/^\n//;t改行がPSの前にある場合は、それを削除して行を印刷します
  • s/^(\S+|\s+)(.*)\n/\2\n\1/;ta改行の直後に非スペース文字列またはスペース文字列を挿入してループします:a

この-rスイッチにより、正規表現が見やすくなります ( grouping (...)、alternation ...|...、および one-or-more のメタ文字+は、バックスラッシュ接頭辞の必要性から解放されます)。

別:

sed -E 'G;:a;s/^(\S+)(\s*)(.*\n)/\3\2\1/;ta;s/.//' file

注: 行を逆にするには、上記のソリューションを次のように適用します。

sed -E 'G;:a;/^(.)(.*\n)/\2\1/;ta;s/.//' file
于 2012-10-28T20:33:32.860 に答える
2

アンサー

この質問はとタグ付けされていたので、私の最初の答えは次のとおりです。

最初に (次のものが含まれている_場合、表示されたスペースをマークするために任意を使用しa.txtますdo to what:

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

より、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

抑制された重複単語+ごとに 1 つあります。

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+

答え

ソリューションを探している人が多いため、単純な方法があります。

xargs < <(uniq <(tac <(tr \  \\n <<<'do do to what what what what')))
what to do

これは次のように書くことができます:

tr \  \\n <<<'do do to what what what what' | tac | uniq | xargs 
what to do

またはいくつかのスクリプトを使用しても:

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
}

しましょう:

revcnt <<<'do do to what what what what' 
what+++ to do+

または純粋な

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

送信された文字列は、引数として送信する必要があります。

revcnt do do to what what what what
what+++ to do+

または、標準入力(またはファイルから) の処理が必要な場合:

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
}

したがって、複数の行を処理できます。

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+
于 2012-10-28T12:02:11.370 に答える
0

ベルンハルトが言ったように、tacここで使用できます:

#!/usr/bin/env bash
set -eu
echo '1 2 3
2 3 4
3 4 5' | while IFS= read -r; do
    echo -n "$REPLY " | tac -s' '
    echo
done

$ ./1.sh
3 2 1 
4 3 2 
5 4 3 

私の例はもっと役立つと思います。

于 2015-07-20T15:55:12.793 に答える
0

これにはperlが必要かもしれません:

perl -F -lane '@rev=reverse(@F);print "@rev"' your_file
于 2012-10-29T13:23:21.363 に答える