テキストファイル(またはstdin)の行の順序を逆にして、各行の内容を保持したいと思います。
つまり、次のように始まります。
foo
bar
baz
私は終わりにしたいと思います
baz
bar
foo
このための標準的なUNIXコマンドラインユーティリティはありますか?
テキストファイル(またはstdin)の行の順序を逆にして、各行の内容を保持したいと思います。
つまり、次のように始まります。
foo
bar
baz
私は終わりにしたいと思います
baz
bar
foo
このための標準的なUNIXコマンドラインユーティリティはありますか?
回答:
brew install coreutils
(gtac
デフォルトでインストール)。
echo -n "abc\ndee" > test; tac test
。
あります、よく知られているsedのトリック:
# reverse order of lines (emulates "tac")
# bug/feature in HHsed v1.5 causes blank lines to be deleted
sed '1!G;h;$!d' # method 1
sed -n '1!G;h;$p' # method 2
(説明:バッファを保持するために先頭以外の行を追加し、行をスワップしてバッファを保持し、最後に行を出力します)
または、awkワンライナーから(より高速に実行して):
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file*
思い出せないなら
perl -e 'print reverse <>'
GNUユーティリティを備えたシステムでは、他の答えは単純ですが、すべての世界がGNU / Linuxであるわけではありません...
tail -r
、tac は利用できません。
tac
メモリに収まらない任意の大きなファイルを処理することが期待されます(ただし、行の長さは制限されています)。このsed
ようなファイルに対してソリューションが機能するかどうかは不明です。
コマンドの最後に次のように入力します。
| tac
tacは、あなたが求めていることを正確に実行します。「最後の行を最初にして、各FILEを標準出力に書き込みます」。
tacはcat :-)の反対です。
tac
コマンドの値を説明してください。これは、同じ主題を検索してしまう可能性のある新しいユーザーに役立ちます。
vim
使用中の場合
:g/^/m0
$ (tac 2> /dev/null || tail -r)
tac
Linuxで機能するを試してください。それが機能しない場合はtail -r
、BSDおよびOSX で機能するを試してください。
tac myfile.txt
でしょうか-何が欠けていますか?
tail -r
場合にフォールバックするtac
。tac
POSIXに準拠していません。どちらもありませんtail -r
。それでも絶対確実というわけではありませんが、これにより、動作する確率が向上します。
tac
が利用可能であるが、RAMが不足し、巨大な入力ストリームを消費する途中でスワップする場合 これは失敗し、tail -r
ストリームの残りの部分の処理に成功して、不正な結果をもたらします。
brew install coreutils
使用gtac
しtac
ます。gtac
たとえば、クロスプラットフォーム(Linux、OSX)を使用するシェルスクリプトが必要な場合は、別名としてtacを追加します
次のコマンドを試してください。
grep -n "" myfile.txt | sort -r -n | gawk -F : "{ print $2 }"
sed 's/^[0-9]*://g'
nl
デフォルトでは空行の番号付けに失敗します。この-ba
オプションは一部のシステムで使用できますが、普遍的ではありません(HP / UXが思い浮かびますが、使用しない方がいいと思います)一方で、(この場合は空の)正規表現に一致するすべての行にgrep -n
常に番号が付けられます。
cut -d: -f2-
Just Bash :)(4.0+)
function print_reversed {
local lines i
readarray -t lines
for (( i = ${#lines[@]}; i--; )); do
printf '%s\n' "${lines[i]}"
done
}
print_reversed < file
-nenenenenenene
を含むファイルでこれを試して、人々がのprintf '%s\n'
代わりに常に使用することを推奨する理由を確認してくださいecho
。
最も簡単な方法は、tac
コマンドを使用することです。tac
あるcat
のは逆。例:
$ cat order.txt
roger shah
armin van buuren
fpga vhdl arduino c++ java gridgain
$ tac order.txt > inverted_file.txt
$ cat inverted_file.txt
fpga vhdl arduino c++ java gridgain
armin van buuren
roger shah
私は「tail -r」の回答が本当に好きですが、私の好きなgawkの回答は....
gawk '{ L[n++] = $0 }
END { while(n--)
print L[n] }' file
mawk
Ubuntu 14.04 LTSでテスト済み-動作するため、GNU awk固有ではありません。+1
n++
次のものと置き換えることができますNR
以下を編集すると、1から10までの数字のランダムにソートされたリストが生成されます。
seq 1 10 | sort -R | tee /tmp/lst |cat <(cat /tmp/lst) <(echo '-------') **...**
ドットはリストを逆にする実際のコマンドに置き換えられます
タック
seq 1 10 | sort -R | tee /tmp/lst |cat <(cat /tmp/lst) <(echo '-------') \
<(tac)
python:sys.stdinで[::-1]を使用
seq 1 10 | sort -R | tee /tmp/lst |cat <(cat /tmp/lst) <(echo '-------') \
<(python -c "import sys; print(''.join(([line for line in sys.stdin])[::-1]))")
tac
シェルスクリプト内で使用できるクロスOS(つまり、OSX、Linux)ソリューションの場合は、他の人が上記のようにhomebrewを使用し、次のように単にtacをエイリアスします。
libをインストールする
MacOSの場合
brew install coreutils
Linux debianの場合
sudo apt-get update
sudo apt-get install coreutils
次にエイリアスを追加します
echo "alias tac='gtac'" >> ~/.bash_aliases (or wherever you load aliases)
source ~/.bash_aliases
tac myfile.txt
n
非常に大きなテキストファイルの最後の行を効率的に取得したい場合があります。
私が最初に試したのはですがtail -n 10000000 file.txt > ans.txt
、非常に遅いことがわかりました。tail
その場所にシークしてから、結果を印刷するために戻る必要があるためです。
気づいたら、別のソリューションに切り替えますtac file.txt | head -n 10000000 > ans.txt
。今回は、シーク位置が最後から目的の場所に移動するだけで、時間を50%節約できます。
お持ち帰りメッセージ:
オプションがないtac file.txt | head -n n
場合に使用tail
し-r
ます。
Emacsユーザーの場合:(C-x h
ファイル全体を選択)、次にM-x reverse-region
。また、パーツまたはラインを選択し、それらを元に戻す場合にのみ機能します。
あなたがそれを行うことができますvim
stdin
し、stdout
。を使用ex
してPOSIXに準拠することもできます。vim
は単なるのビジュアルモードですex
。実際には、あなたが使用することができex
てvim -e
かvim -E
(改善されたex
モード)。
vim
のようなツールとは異なりsed
、ファイルは編集用にバッファsed
されますが、ストリームには使用されます。を使用できるawk
場合もありますが、手動ですべてを変数にバッファリングする必要があります。
アイデアは次のようにすることです:
g/^/m0
です。これは、各行についてグローバルに意味しg
ます。何にでも一致する行の先頭に一致し^
ます。アドレス0、つまり1行目の後に移動しますm0
。%p
です。これは、すべての行の範囲を意味し%
ます。行を印刷しますp
。q!
です。これは、終了することを意味しq
ます。力強く!
。# Generate a newline delimited sequence of 1 to 10
$ seq 10
1
2
3
4
5
6
7
8
9
10
# Use - to read from stdin.
# vim has a delay and annoying 'Vim: Reading from stdin...' output
# if you use - to read from stdin. Use --not-a-term to hide output.
# --not-a-term requires vim 8.0.1308 (Nov 2017)
# Use -E for improved ex mode. -e would work here too since I'm not
# using any improved ex mode features.
# each of the commands I explained above are specified with a + sign
# and are run sequentially.
$ seq 10 | vim - --not-a-term -Es +'g/^/m0' +'%p' +'q!'
10
9
8
7
6
5
4
3
2
1
# non improved ex mode works here too, -e.
$ seq 10 | vim - --not-a-term -es +'g/^/m0' +'%p' +'q!'
# If you don't have --not-a-term, use /dev/stdin
seq 10 | vim -E +'g/^/m0' +'%p' +'q!' /dev/stdin
# POSIX compliant (maybe)
# POSIX compliant ex doesn't allow using + sign to specify commands.
# It also might not allow running multiple commands sequentially.
# The docs say "Implementations may support more than a single -c"
# If yours does support multiple -c
$ seq 10 | ex -c "execute -c 'g/^/m0' -c '%p' -c 'q!' /dev/stdin
# If not, you can chain them with the bar, |. This is same as shell
# piping. It's more like shell semi-colon, ;.
# The g command consumes the |, so you can use execute to prevent that.
# Not sure if execute and | is POSIX compliant.
seq 10 | ex -c "execute 'g/^/m0' | %p | q!" /dev/stdin
これを再利用可能にする方法
私が呼び出すスクリプトved
(vimエディターのようなsed
)を使用して、vimを編集しますstdin
。これをved
パスで呼び出されるファイルに追加します。
#!/usr/bin/env sh
vim - --not-a-term -Es "$@" +'%p | q!'
vim +
では+'%p' +'q!'
10個のコマンドに制限されているため、私はの代わりに1つのコマンドを使用しています。したがって、それらをマージすると、は8個ではなく"$@"
9個の+
コマンドを持つことができます。
次に、次のことができます。
seq 10 | ved +'g/^/m0'
vim 8がない場合は、ved
代わりに次のコードを入力してください。
#!/usr/bin/env sh
vim -E "$@" +'%p | q!' /dev/stdin
rev
text here
または
rev <file>
または
rev texthere
sort -r < filename
または
rev < filename
sort -r
入力が既にソートされている場合にのみ機能しますが、ここではそうではありません。rev
行ごとの文字を逆にしますが、スコットが要求したものではない行の順序をそのまま維持します。したがって、この答えは実際にはまったく答えではありません。
perl -e 'print reverse <>'
が、おそらく他の方法にも適用されます)。