各行を11回コピーし、各行の最後の「1」を2〜12に増やす方法


9

ファイルに複数の行があり、各行を11回コピー(各行を12行に変換)し、各行の最後の "1"をインクリメントして、12行に "1"から " 12 "、" 1 "が最初にあった場所。各行に「1」の他の出現がある可能性がありますが、増分したい「1」は常に各行の最後の出現になります。別の見方をすると、最後の「1」は常に「/ nt /」の後ろにある-「/ nt / 1」のように(そして、それは常に各行で「/ nt / 1」の唯一のオカレンスになります) 。

したがって、たとえば、私が持っている場合:

1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah

それを次のように変えたいです。

1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
1stlineblahblahblah/nt/3blah
1stlineblahblahblah/nt/4blah
1stlineblahblahblah/nt/5blah
1stlineblahblahblah/nt/6blah
1stlineblahblahblah/nt/7blah
1stlineblahblahblah/nt/8blah
1stlineblahblahblah/nt/9blah
1stlineblahblahblah/nt/10blah
1stlineblahblahblah/nt/11blah
1stlineblahblahblah/nt/12blah
2ndlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah
...

私は以前にコマンドを見つけました:

:for i in range(0,12) | put ='1stlineblahblahblah/nt/'.i.'blah' | endfor

この目的のために機能しますが、各行に対してこのコマンドを手動で実行し、各行を自分で入力(またはコピーして貼り付け)する必要があります。すでにファイルにある行を取得し、各行を12に変換する1つのコマンドを実行する方法はありますか。

これで私を助けることができる人に前もって感謝します。また、これが2番目の質問であることにも注意したいと思います。最初の質問に対して、いくつかの迅速で効果的な解決策が得られたことを嬉しく思います。

回答:


8

これは問題を解決する置換です:

:%s/\(.*\)1\(.*\)/\=join(map(range(1, 12), 'submatch(1) . v:val . submatch(2)'), "\n")

置換は「1」が含まれていると前にテキストをキャプチャし、各ラインと一致する{c1}とした後、{c2}「1」の最後を。一致した行ごとに、1から12までの数値の範囲{n}マップされ、フォームの12行が作成れます{c1}{n}{c2}。12行の各グループは、関連付けられた、最初に一致した行を置き換えます。

を参照してください:h sub-replace-expression


2
すばらしい、1行のコマンドです。数週間前に私が最初に尋ねた質問に対しても、エレガントな1行のソリューションを見つけたのを覚えています。とてもいい仕事です。どうもありがとうございました。また、上の行全体を入力せずに(または前のコマンドのリストをスクロールする必要なく)覚えやすいコマンドまたは関数を実行できるように、これを_vimrcファイルに配置する方法があると思いますが、私は_vimrc構文にまだ慣れていないので、その方法を知ることができません。
ablewasiereisawelba

10

あなたはこれを行うことができます

  1. マクロを記録し、
  2. globalexコマンドを使用して、ファイルの各行に対してマクロをn回実行します。

マクロの記録後、記録中に行われた変更を元に戻します。そうしないと、最初の行にn + 1行追加され、連続する行にはn行追加されます。

マクロをaレジスターに記録する

qayyp$?\d<CR><C-A>q

これにより、次のコマンドがレジスタaqa...q)に記録されます。

  • yyp:現在の行を複製
  • $:行末に移動
  • ?\d<CR>:1桁後方検索
  • <C-A>:カーソルの下の桁を1ずつ増やす

マクロが記録されたら、元に戻す(uu)または現在の行を削除する()ことにより、記録中に行った変更を削除しますdd。次に11、グローバルコマンドを使用して、ファイル内の各行に対してマクロ(または任意の回数)を繰り返します。

:g//normal 11@a

2
動いた!ありがとう、とても良いです。私の代わりに私がWindowsでのgvimを使用していますので、追加のCtrlキーを押しながら強調し、すべてで最初に問題を抱えていた...しかし、私はクイック検索を行なったし、このスレッドを発見した- stackoverflow.com/questions/289681/... - I nnvimap <kPlus> <Ca> nnoremap <kMinus> <Cx>を_vimrcに置くという提案を使用して、加算と減算に「+」キーと「-」キーを使用できるようにしました。また、グローバルコマンドは:g // normal 11 @ aである必要がありましたが、簡単にわかりました。ありがとうございました!
ablewasiereisawelba

6

二通り:

マクロを使用してください!

で始まります

1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah

カーソルを最初の行に置いて

qqyyp$?\d<CR><Ctrl-a>q
10@q

どれが:

qq qレジスタへのマクロの記録を開始します

yyp 現在の行をヤンクして、下に貼り付けます

$?\d<CR> 行の最後に移動し、最初の桁を逆向きに探します

<Ctrl-a> 数を増やす

q マクロの記録を停止します。

これはあなたに残します:

1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah

カーソルを2行目に置きます。このマクロを必要なだけ繰り返します(たとえば、10 @ qで10回繰り返します)。このプロセスをラインごとに自動化する場合は、各ラインでグローバルに実行します。

:g//normal 11@q

または、新しいバージョンのvimの場合:必要な行を何度でも貼り付け、インクリメントする桁をビジュアルブロックで選択して、を押しg <Ctrl-a>ます。これにより、ビジュアルブロックのすべての数値が増加します。ただし、これはより手動のプロセスです。


1
すごい、私はg <c-a>方法を知りませんでした。共有いただきありがとうございます。
kbaは、2016

1
@fruglemonkey回答の最初の部分は上記のものと同じですが、それでもありがとうございます。2番目の部分は、私は(私が何か間違っているのでない限り)うまくいくとは思わないので、正しいバージョンを使用してはなりません。
ablewasiereisawelba

5

このようなワンショットタスクにはマクロを使用するのが最も簡単です。q+レジスタの名前でマクロの記録を開始し、タスクを1回実行するだけです。ここに繰り返し可能なタスクが1つあります。

  • 行を選択してください
  • ヤンク
  • 貼り付け(次の行に移動します)
  • 行末に移動
  • 一言戻る
  • 1ずつ増加

a通常モードで、登録に必要なキーストロークを記録します。

qayyp$b<c-a>.

もう一度行を削除して、マクロを11回実行すると1行で正しい結果が得られるかどうかをテストします。

11@a

します!もう一度やり直して、2番目のマクロでプロセス全体を自動化しますb

qb11@aj

これ@bで、ファイルの終わりまで実行でき、必要な出力が生成されます。複雑に聞こえるかもしれませんが、通常の編集パターンに慣れた後は、そうではありません。


何か悪いことをしているかどうかはわかりませんが、うまくいっていないようです。私はあなたが書いたものに従いましたが、おそらく私は何かを誤解しているか、何かを適切に実行しませんでした。(行の最後の番号ではなく、最初の行の番号が増えています。)返信いただきありがとうございます。
ablewasiereisawelba

3
最初のマクロはだと思いますqaVyp$b<c-a>。またはそれ以上qayyp$b<c-a>
Karl YngveLervåg16年

1
ありがとう、@KarlYngveLervåg、そうです、私はマクロを修正しました。
kbaはモニカの2016

2
Argh :( @ablewasiereisawelbaを徹底してくれてありがとう。qqyyp$?\d<CR><Ctrl-a>q最後の数字を検索するので、@ fruglemonkeyと@jjaderbergのマクロの方がいいと思います。完全を
期す

2
@kba私は、誰かが時間と労力を費やして私の質問に答えるなら、少なくとも他の人から有効な解決策をすでに見つけていたとしても、少なくとも彼の解決策を試すことができると思いました。私はあなたの努力に感謝します-そしてそれがあなたが気分を良くするならば、あなたはまだ私の前のマイルです。:)
ablewasiereisawelba 2016

2

次のマクロを保存して、各行に使用します。

qqyy11p/\/\zs1<CR><C-v>10jg<C-a>q

他の回答との主な違いは、これはg<C-a>各行を異なる番号でインクリメントする列選択を利用することです。詳細:help v_g_CTRL-Aを確認してください。また\zs、パターンの開始位置を選択して、検索後にカーソルが番号で停止するようにしました。

これを機能させるには、最新バージョンのVimが必要です。


1
@fruglemonkeyもそれを提案しました。これはクールな機能ですが、7.4.754以降、すべてのディストリビューションにはまだ出荷されていません。
kbaはモニカの2016

申し訳ありませんが見逃してしまいました
Vitor 2016

1
@Vitor私はgVim 7.4しか持っていないのでg<C-a>、@ fruglemonkeyを実行することはできないと思います。マクロを試すときに注意する必要があります- g<C-a>パーツに到達する直前で、インクリメントしようとしている最後の「1」文字ではなく、ブロックが強調表示されますが、最初の「1」の前の文字です。 "ブロックが強調表示される文字。(また、私はそれは持っていると思うyy11p10j私はしているよ以来、マクロに追加 - 12の合計11行)
ablewasiereisawelba

1
ご意見をいただきありがとうございます。それに応じて答えを更新しました。使用することを決めました\zsが、私は単に単にl後を追加することもできました<CR>
Vitor 2016

1
おそらく、正規表現検索に影響する設定がvimrcにあります。Vimをで起動して、もう一度試してくださいvim -u NONE。私はそれをやったばかりで、これは完璧に機能します!実際、前のスラッシュが必要なため、検索が最初の1と一致する方法はありません。
Vitor
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.