私はファイルを持っています。それを「a.txt」と呼びましょう。このファイルには次のテキスト行が含まれています
do to what
このテキストの順序を逆にして次のように表示する SED コマンドが何であるか疑問に思っています
what to do
ある種の追加を行う必要がありますか? 「to」に「do」を追加すると、次のようになります
to ++ do (明確にするために ++ を使用)
私はファイルを持っています。それを「a.txt」と呼びましょう。このファイルには次のテキスト行が含まれています
do to what
このテキストの順序を逆にして次のように表示する SED コマンドが何であるか疑問に思っています
what to do
ある種の追加を行う必要がありますか? 「to」に「do」を追加すると、次のようになります
to ++ do (明確にするために ++ を使用)
私はtac
関連する何かをすることができることを知っています
$ cat file
do to what
$ tac -s' ' file
what to do $
ここで、-s
は区切り文字を定義します。これはデフォルトでは改行です。
私は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
これはうまくいくかもしれません(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
この質問はsedとタグ付けされていたので、私の最初の答えは次のとおりです。
最初に (次のものが含まれている_
場合、表示されたスペースをマークするために任意を使用し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+
しかし、単純なbashソリューションを探している人が多いため、単純な方法があります。
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
またはいくつかのbashスクリプトを使用しても:
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+
ベルンハルトが言ったように、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
私の例はもっと役立つと思います。
これにはperlが必要かもしれません:
perl -F -lane '@rev=reverse(@F);print "@rev"' your_file