Vim で 2 つの行のブロックをマージしたいと思います。つまり、行 kから lを取り、それらを行mから nに追加します。擬似コードの説明が必要な場合: [line[k+i] + line[m+i] for i in range(min(l-k, n-m)+1)]
.
例えば、
abc
def
...
123
45
...
なるべき
abc123
def45
行ごとに手動でコピーして貼り付けずにこれを行う良い方法はありますか?
Vim で 2 つの行のブロックをマージしたいと思います。つまり、行 kから lを取り、それらを行mから nに追加します。擬似コードの説明が必要な場合: [line[k+i] + line[m+i] for i in range(min(l-k, n-m)+1)]
.
例えば、
abc
def
...
123
45
...
なるべき
abc123
def45
行ごとに手動でコピーして貼り付けずにこれを行う良い方法はありますか?
確かに、これらすべてを 1 回のコピー/貼り付け (ブロック モード選択を使用) で行うことができますが、それはあなたが望んでいることではないと思います。
Exコマンドだけでこれを行いたい場合
:5,8del | let l=split(@") | 1,4s/$/\=remove(l,0)/
変身します
work it
make it
do it
makes us
harder
better
faster
stronger
~
の中へ
work it harder
make it better
do it faster
makes us stronger
~
更新:この多くの賛成票を含む回答は、より完全な説明に値します。
Vim では、パイプ文字 ( |
) を使用して複数の Ex コマンドを連結できるため、上記は次のようになります。
:5,8del
:let l=split(@")
:1,4s/$/\=remove(l,0)/
多くの Ex コマンドは、行の範囲を前置引数として受け入れます。上記の場合、コマンドが動作する行を指定する前5,8
のdel
と1,4
前のです。s///
del
指定された行を削除します。レジスタ引数を取ることができますが、引数が与えられていない場合@"
、通常モードで削除するのと同じように、名前のないレジスタに行をダンプします。 let l=split(@")
次に、デフォルトの区切り文字である空白を使用して、削除された行をリストに分割します。次のように、削除された行に空白が含まれる入力で適切に動作するには:
more than
hour
our
never
ever
after
work is
over
~
「work is」が 2 つのリスト要素に分割されるのを防ぐために、別の区切り文字を指定する必要がありますlet l=split(@","\n")
。
最後に、置換s/$/\=remove(l,0)/
では、各行の終わり ( $
) を式の値に置き換えますremove(l,0)
。 remove(l,0)
listl
を変更し、最初の要素を削除して返します。これにより、削除された行を読み取った順に置き換えることができます。代わりに、 を使用して、削除された行を逆の順序で置き換えることができremove(l,-1)
ます。
:global
、、、:move
およびコマンドを組み合わせることで、問題を解決するエレガントで簡潔なExコマンドを取得でき:join
ます。行の最初のブロックがバッファの最初の行から始まり、カーソルが2番目のブロックの最初の行の直前の行にあると仮定すると、コマンドは次のようになります。
:1,g/^/''+m.|-j!
この手法の詳細な説明については、同様の質問「<ahref="https://stackoverflow.com/q/9658612/254635">箱から出して「貼り付け-d」」の動作を実現する方法に対する私の回答を参照してください。 Vimで?」
行のブロックを結合するには、次の手順を実行する必要があります。
jj
CTRL-v
$
CTRL-END
x
kk$
p
動きは最高のものではありません (私は専門家ではありません) が、希望どおりに動作します。それの短いバージョンがあることを願っています。
この手法がうまく機能するための前提条件は次のとおりです。
abc
とdef
) は、同じ長さのXORを持ちます。これを行う方法は次のとおりです(最初の行にカーソルを置きます):
qama:5<CR>y$'a$p:5<CR>dd'ajq3@a
次の 2 つのことを知っておく必要があります。
何が起こっているかは次のとおりです。
qa
q
の「バッファ」に次までのすべてを記録しますa
。ma
現在の行にマークを作成します。:5<CR>
次のグループに行きます。y$
行の残りをヤンクします。'a
以前に設定したマークに戻ります。$p
行末に貼り付けます。:5<CR>
2 番目のグループの最初の行に戻ります。dd
削除します。'a
マークに戻ります。jq
1 行下に移動し、記録を停止します。3@a
行ごとにアクションを繰り返します(私の場合は3)他の場所で述べたように、ブロック選択が有効です。ただし、次のバリアントを使用することもできます。
:!tail -n -6 % | paste -d '\0' % - | head -n 5
この方法は、UNIX コマンド ラインに依存しています。このpaste
ユーティリティは、このような行のマージを処理するために作成されました。
PASTE(1) BSD General Commands Manual PASTE(1)
NAME
paste -- merge corresponding or subsequent lines of files
SYNOPSIS
paste [-s] [-d list] file ...
DESCRIPTION
The paste utility concatenates the corresponding lines of the given input files, replacing all but the last file's newline characters with a single tab character,
and writes the resulting lines to standard output. If end-of-file is reached on an input file while other input files still contain data, the file is treated as if
it were an endless source of empty lines.
あまり複雑にすることはないと思います。
( :set virtualedit=all
)
Select ブロック 123 以下に virtualedit を設定するだけです。
最初の列の後に入れます。
abc 123
def 45
... ...
1 つのスペースとの間の複数のスペースを削除します。
:%s/\s\{2,}/ /g
サンプルデータはramionのものと同じです。
:1,4s/$/\=getline(line('.')+4)/ | 5,8d
複雑な繰り返しを使用します:)
これを考えると:
aaa
bbb
ccc
AAA
BBB
CCC
最初の行にカーソルを置いて、次のように押します。
qa}jdd''pkJxjq
を必要な回数だけ押し@a
ます (後で を使用することもできます)。@@
最終的には次のようになります。
aaaAAA
bbbBBB
cccCCC
(さらに改行。)
説明:
qa
で複雑な繰り返しの録音を開始しますa
}
次の空行にジャンプします
jdd
次の行を削除します
''
最後のジャンプの前の位置に戻る
p
削除された行を現在の行の下に貼り付けます
kJ
現在の行を前の行の末尾に追加します
x
J
結合された行の間に追加されるスペースを削除します。スペースが必要な場合は、これを省略できます
j
次の行に移動
q
複雑な繰り返し録音を終了する
その後、 を使用@a
して に格納された複雑な繰り返しを実行し、を使用して最後に実行された複雑な繰り返しを再実行a
できます。@@
これを達成する方法はたくさんあります。次の 2 つの方法のいずれかを使用して、2 つのテキスト ブロックをマージします。
最初のブロックが 1 行目にあり、2 番目のブロックが 10 行目から始まり、カーソルの初期位置が 1 行目であるとします。
(\n はエンターキーを押すことを意味します。)
1. abc
def
ghi
10. 123
456
789
コマンドを使用したマクロ: コピー、貼り付け、および結合。
qaqqa:+9y\npkJjq2@a10G3dd
コマンドを使用したマクロで、n 番目の行番号で行を移動して結合します。
qcqqc:10m .\nkJjq2@c