Vimで選択した行の順序を逆にするにはどうすればよいですか?


94

たとえば、次の4行がある場合:

1行
目2行
目3行
目4行目

私はそれらを逆にしたい

4行
目3行
目2行
目1行目

Vimでこれを行うにはどうすればよいですか?




1
:command! -bar -range=% Reverse <line1>,<line2>global/^/m<line1>-1 vi.stackexchange.com/a/2107/10254
qeatzy

回答:


86

ファイル内のすべての行を反転するには、

:g/^/m0

説明については

:help 12.4

また、行の範囲だけを反転する方法も示しています。


12
正確なヘルプセクションのヒントです。要約すると:1.あなたは(「」使用して、私は、マーカーに名前を逆にしたい最後の行にマーカーを設定しma、)ブロックの最初の行に2カーソル移動、3タイプ:'a,.g/^/m 'a
ブレント・ファウスト

68

目的の行を選択し、を押し!て、結果のプロンプトでtaclaを介して行をパイプします:'<,'>!tac。詳細man tacを参照してください。


4
線を選択するには、を使用shift+vして視覚的な線モードに入り、選択に線jを追加します。
ウィスバッキー

これも、Windowsで動作することを確認できgvimます!それ以外の場合、絶対行番号を使用する必要があります(相対を使用することもできますが、注意する必要があります):g/^/m0(これも覚えるのが非常に困難です)...あなたは上にいますが、それは100%vimscriptではありませんが、気にする人は:P
dylnmc

tacは完全にネイティブなvim処理ではありませんが、「m'oveコマンドは行番号を取得するため、常に合理的ではありません。私はしばしば範囲の一部としてマークを使用するので:.,'a!tac、最小限の労力で機能します。
スタッド

を使用した後shift+v、を使用}して次の段落に到達するか、空の垂直スペースを使用できます。また、man tac: concatenate and print files in reverse
ニロン

33

Mac OS Xでは、tac存在しませんが、tail -r同じ効果を使用できます:

:%!tail -r

これは視覚モードでもうまく機能します。

:'<,'>!tail -r

tail(1)のマンページからの抜粋:

-rオプションを使用すると、入力が行ごとに逆順に表示されます。さらに、このオプションは、-b、-c、および-nオプションの意味を変更します。-rオプションを指定すると、これらのオプションは、表示を開始する入力の先頭または末尾からのバイト、行またはブロックの代わりに、表示するバイト、行または512バイトブロックの数を指定します。 -rオプションのデフォルトでは、すべての入力が表示されます。


3
優れた!したがって、OS Xで「tac」を提供するには:alias tac='tail -r'
ブレントファウスト

4
brew install coreutilsを使用することもできますgtac
アンドリューマーシャル14

1
天才。使用することを考えたことがありません!このタイプの視覚的なライン操作のためのコマンド。
チャーリーダルサス

3

ビジュアルモードに慣れている場合:
1 :set nu. を使用して、反転したい選択の上の行番号を特定します。
2. Shift-V反転したい選択を強調表示します(視覚モード)。
3. :g/^/m <Line number from step 1>

ビジュアルモードでは:'<,'>g/^/m <Line number>、3からコマンドを入力したときと同じように自動的に表示されることに注意してください 。

このコマンドは、選択を一度に1行ずつ、指定した行番号に移動することで機能します。2番目の項目が指定された行番号にプッシュされると、最初の項目が行番号+ 1にプッシュされます。次に3番目の項目が1番目と2番目にプッシュされます逆順リスト。


4
'<行番号を手動で入力する代わりにを使用できます。1行前に選択を開始して実行し:'<,'>g/^/m'<ます。
パレック

3

のコマンド:Rev[erse]とオプションのマッピングなvimrcので、このレシピの非自明な手順を覚えて実行する必要はありません。

" Reverse the lines of the whole file or a visually highlighted block.
    " :Rev is a shorter prefix you can use.
    " Adapted from http://tech.groups.yahoo.com/group/vim/message/34305
command! -nargs=0 -bar -range=% Reverse
    \       let save_mark_t = getpos("'t")
    \<bar>      <line2>kt
    \<bar>      exe "<line1>,<line2>g/^/m't"
    \<bar>  call setpos("'t", save_mark_t)

nmap <Leader>r :Reverse<CR>
xmap <Leader>r :Reverse<CR>

(印刷可能な文字をマッピングするためのアドバイス:xmapとして、ビジュアルモードにマップしますが、選択モードにはマップしません:help mapmode-x。)

(ベース:http : //tech.groups.yahoo.com/group/vim/message/34305


これは、受け入れられた回答IMOである必要があります。最も一般的に有用であり、覚えておく必要はありません:'<,'>g/^/m'<:)
エリオット

1
@エリオット、ありがとう!:)(「ボーナスコンテンツ」を少し追加しました。;))
アーロントーマ

この場合、選択開始-1を指定するにはどうすればよいですか?なぜなら、この時点で移動が始まるからです。
SergioAraujo

@SergioAraujo::-1,+1Revあなたが探しているもののようなものですか?反転したい範囲を視覚的に選択できることを知ってくださいV7j:Rev。例:。それがあなたの質問に答えない場合、私はそれを理解していませんので、あなたは私のためにそれを詳述するか、言い換える必要があります。
アーロントーマ

1

3行目にいるとしましょう。したがって、範囲は3〜6です。入力するだけです。

:3,6g/^/m2

1
現在の行の番号を暗黙的に残すことができます。カーソルを範囲の最初の行に置くと:,6g/^/m2、に短縮できます。または範囲の最後の行にある場合::3,g/^/m2; そして:3,6g/^/m2、ファイル内のどこからでも動作します。
アーロントーマ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.