Bagaimana saya bisa menggunakan angka berurutan dalam perintah pengganti Ex-style?

8

Misalnya, katakanlah saya ingin memasukkan angka sebelum setiap baris yang dimulai dengan kata "Do". Perintahnya akan terlihat seperti :%s/^(Do )/1. \1/, tapi apa yang bisa saya lakukan sehingga akan menerapkan angka secara berurutan alih-alih nomor yang sama setiap kali?

Perhatikan bahwa saya menyadari banyak cara untuk melakukan ini menggunakan makro dan Ctrl-A, tetapi untuk digunakan dalam perintah Ex-mode yang lebih rumit, saya ingin mengetahui jawaban untuk pertanyaan judul yang sebenarnya.

Untuk contoh lain di mana pendekatan makro tidak akan semudah itu, katakanlah saya ingin menambahkan nomor ke semua contoh kata "Bagian", dan minta mereka dinomori secara berurutan tetapi memulai kembali penghitungan setelah setiap baris yang dimulai "Bab". Perintah Ex-mode yang hampir dapat melakukan ini, simpan untuk benar-benar menambah nomor yang akan ditambahkan, adalah:

:g/^Chapter/;/^Chapter/-s/Section\zs/ 1/g

Anda dapat melihat bahwa metode mudah penambahan angka dalam perintah pengganti mode Ex bisa sangat berguna.

Wildcard
sumber

Jawaban:

8

Perintah ini melakukan apa yang Anda inginkan:

:let i = 1|g/^Do/s/^/\=i/|let i = i + 1

Penjelasan…

  • let i = 1menginisialisasi penghitung i,
  • g/^Do/s/^/\=i/tergantung ipada setiap baris dimulai dengan Do,
  • let i = i + 1kenaikan i.

Kuncinya adalah bahwa kenaikan terjadi sebelum substitusi berikutnya.

--- sunting ---

Jika kita menggunakan substitusi tunggal, penghitung hanya akan bertambah satu kali, setelah semuanya dilakukan.

Karena kami melakukan banyak penggantian - satu untuk setiap baris yang cocok - alih-alih satu, pencacah ditambahkan dengan benar sebelum penggantian berikutnya.

romainl
sumber
Bagaimana Anda bisa meletakkan titik setelah nomor itu? \=i. adalah ekspresi yang tidak valid.
David Conrad
2
@ Davidvidon, .menjadi operator gabungan dalam \=ekspresi. Jadi s//\=i . '. '/akan menambahkan '. ' Lihat :help expression-syntax.
Wildcard
kenaikan terjadi setelah penggantian
Christian Brabandt
@ChristianBrabandt, oops, saya tidak sengaja berkata sepatah kata pun.
romainl