最初の行が最後に表示され、最後の行が最初に表示されるように行の順序を逆にするにはどうすればよいですか?(バッファー内のすべての行、アドレス範囲、または行単位の視覚モード選択である可能性があります。)
変身したい
rat
ox
tiger
⋮
dog
pig
に
pig
dog
⋮
tiger
ox
rat
などの外部コマンドに頼ることなくtac
。
最初の行が最後に表示され、最後の行が最初に表示されるように行の順序を逆にするにはどうすればよいですか?(バッファー内のすべての行、アドレス範囲、または行単位の視覚モード選択である可能性があります。)
変身したい
rat
ox
tiger
⋮
dog
pig
に
pig
dog
⋮
tiger
ox
rat
などの外部コマンドに頼ることなくtac
。
回答:
グローバルの力はここで機能します:
:g/^/exe "normal ddggP"
または、もっと簡単(@tommcdoに感謝)
:g/^/move 0
最初の行はすべての行に一致し、行ごとに削除してファイルの上部に貼り付けます。ファイル内を移動すると、テキストが反転します。
2番目も同様にすべての行に一致し、ファイルの先頭に移動します。
注:これらは両方ともファイル全体で機能し、行のサブセットの反転には正しく適用されません。範囲内で機能するソリューションについては、Ingo Karkatの回答を参照してください。
説明:
g
グローバルコマンドは、
/^/
最初(すなわち、すべての行)を持つ任意の行と一致する
exe
次の文字列を実行し
"normal
、通常モードコマンドを実行し
dd
、削除行の
gg
ファイルの先頭に移動
P
現在の位置上記のペーストを
move 0
現在の行を行0の下に移動します(位置1またはファイルの最初の行に配置します)
:normal
コマンドの代わりに、Exコマンドを使用して:move 0
、行をバッファーの先頭に移動できます。
:execute
、コマンドを動的に構築する必要がある場合にのみ必要:execute 'normal' g:user_command
です。
:execute
、既存のコマンドの後に他のExコマンドを後から追加することが多いためです:exe
。後で戻って挿入するよりも、既にある方が便利です。残念ながら、この習慣はこの答えに漏れており、あまり当てはまりません。
:execute
:文字列をとるので、文字列を構築していなくても、通常モードのコマンドが終了する場所を明確に描写します。<esc>
またはモードを終了するものは何でも。繰り返しますが、これは個人的な好みと習慣です。:-)
:9,11g/^/move 8
。...最後の数値は、範囲の先頭から1を引いた値である必要があります(Ingoの回答から適応)。
このワンライナー(あなたの~/.vimrc
)は:Reverse
コマンドを定義します; :global
パーツを直接使用することもできますが、の構文:move
(範囲の開始前に行を反復的にシフトし、それによって範囲を逆にする)を覚えるのは簡単ではありません。
:command! -bar -range=% Reverse <line1>,<line2>global/^/m<line1>-1
<line1>
&<line2>
レンジにこの作業を行うために必要とされる、すなわち::7,9Reverse
(の彼らはしている機能command
ではない、global
またはmove
)。単純:command! -bar -range=% Reverse :global/^/m 0
うも仕事が、唯一のバッファ全体のために...
Pure Vim:
:g/^/m0
説明:
によると
:help multi-repeat
、:g
その従兄弟:v
は2パス方式で動作します。最初のパスは
:g
すべての行が一致することをマークしますが{pattern}
、2番目のパス(ファイルの最初から最後まで見かけ上実行される)はを実行し[cmd]
ます。上記の使用は:g
、行が処理される順序を利用します(おそらく大丈夫ですが、おそらく技術的に保証されていません)。最初にすべての行をマークし、最初のマークされた行をファイルの先頭に移動し、2番目をファイルの先頭に移動し(前に移動した行の上)、3番目のマークされた行(再び以前に移動した上)行)、ファイルの最後の行が先頭に移動するまで続き、ファイルを効果的に反転します。
:g
上から下以外の順序で行を処理した場合、このコマンドは機能しないことに注意してください。
出典:vim wikia ですべての行とgのべき乗を逆にします。
外部コマンドを使用したいくつかの例:
tac
(GNU coreutilsの一部- cat
反転):
:%!tac
tail
BSD / OSX(POSIX準拠ではない):
:%!tail -r
-r
-rオプションを使用すると、入力が行ごとに逆順に表示されます。チェック:
man tar
詳細については。
その他のアイデアについては、以下を参照してください。
:g/^/m0
同じではありません:g/^/move 0
か?
tac
も投稿しました)。しかし、私はダウンボットが繰り返された答えのせいだと疑っています。
機能的なVimLの精神:
:call setline(1, reverse(getline(1, line('$'))))
getline(1, line('$'))
バッファ内のすべての行のリストを返します。 バッファの最後の行を示す'$'
特別な引数ですline()
。reverse(...)
入力リストをインプレースで反転します。reverse(copy(...))
入力リストを変更しない場合に使用する必要があります。setline(1, ...)
指定された行を2番目の引数に置き換えます。2番目の引数がリストの場合、リストの長さと同じ行数がリストのコンテンツに置き換えられます。必要に応じて、範囲(デフォルトの%
バッファー全体)を取るコマンドを定義することもできます
:command! -bar -range=% Reverse call setline(<line1>, reverse(getline(<line1>, <line2>)))
hlsearch
ように(有効になっている場合)ものを強調表示しません:g/
...パフォーマンスはおそらく悪いでしょうか?getline(1, line('$'))
メモリ内のバッファ全体を取得するため。reverse()
それは...のような非常に少ないメモリを取る必要がありますので、その場であると思われる
Vimドキュメントごとusr_12.txt-巧妙なトリック
12.4行の順序を逆にする
:global
コマンドは、と組み合わせることができる:move
逆ファイルで、その結果、最初の行の前にすべての行を移動するコマンド。コマンドは次のとおりです。:global/^/m 0
略称:
:g/^/m 0
^
正規表現は(ラインがブランクであっても)行の先頭にマッチします。この:move
コマンドは、一致する行を神話上の0番目の行の後に移動するため、現在の一致する行がファイルの最初の行になります。ように:global
コマンドを変更する行番号によって混乱されていない、:global
最初のように、ファイル及びプットそれぞれの残りのすべての行と一致するように進みます。これは、一連の行でも機能します。最初に最初の行の上に移動し、でマークし
mt
ます。次に、カーソルを範囲内の最後の行に移動して、次のように入力します。:'t+1,.g/^/m 't
相対番号を使用します。段落は13行目から始まり、4行以上スパムします
:13,13+4g/^/m12