Temukan dan ganti string dalam vim pada banyak baris


353

Saya bisa lakukan :%s/<search_string>/<replace_string>/guntuk mengganti string di file, atau :s/<search_string>/<replace_string>/mengganti di baris saat ini.

Bagaimana saya bisa memilih dan mengganti kata-kata dari garis selektif dalam vim?

Contoh: ganti teks dari baris 6-10, 14-18tetapi bukan dari 11-13.



Jawaban:


255

The :&&perintah mengulangi substitusi terakhir dengan bendera yang sama. Anda dapat menyediakan rentang tambahan untuk itu (dan menggabungkan sebanyak yang Anda suka):

:6,10s/<search_string>/<replace_string>/g | 14,18&&

Jika Anda memiliki banyak rentang , saya lebih suka menggunakan loop:

:for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor

5
Terima kasih. Catatan untuk pengguna di masa depan - :6,10s/<search_string>/<replace_string>/g | :14,18&& | :20,23&& | :28,31&&juga akan berfungsi, forloop membuatnya lebih mudah diingat dan dieksekusi.
mu 無

5
Senang kamu menyukainya! The :pada perintah berikutnya adalah opsional, btw, sehingga Anda dapat menyimpan beberapa keystrokes lebih.
Ingo Karkat

2
:&&akan menghemat ratusan penekanan tombol per minggu. Terima kasih!
pdoherty926

Ia bekerja tanpa 'g' pada akhirnya di vim saya. Jadi mungkin ketika Anda menentukan rentang garis itu tidak perlu bendera global
Tayyar R

3
@TayyarR Rentang ini mencakup garis (secara vertikal, sehingga untuk berbicara), sedangkan bendera 'g' menentukan apakah hanya satu atau semua kecocokan dalam garis (jadi secara horizontal) diganti.
Ingo Karkat

386

Menggantikan semua:

:%s/foo/bar/g

Temukan setiap kemunculan 'foo' (di semua lini), dan gantikan dengan 'bar'.

Untuk jalur tertentu:

:6,10s/foo/bar/g

Ubah setiap 'foo' menjadi 'bar' untuk semua baris dari baris 6 ke baris 10 inklusif.


4
apa tujuan / g di sini? Maaf saya baru
mengenal

4
@RajaAnbazhagan Bagian terakhir dari ungkapan ini, setelah yang terakhir /, adalah di mana Anda menunjukkan tanda untuk operasi. Perintah ini biasanya akan menggantikan pertandingan pertama pada satu baris; Dengan gbendera itu akan menggantikan semua kemunculan.
Litty

17
Anda harus benar-benar referensi sumber Anda (yaitu, vim.wikia.com/wiki/Search_and_replace), jika Anda akan menyalin dan melewati karya orang lain.
Andrew S

2
The %hal melakukan pekerjaan! Kalau tidak, itu hanya kejadian pertama.
Santosh Kumar

8
%=> jalankan perintah ini di semua baris. g=> cocok dengan beberapa kejadian di baris yang sama.
shaahiin

55

Sebagai catatan, alih-alih harus mengetikkan angka garis, cukup sorot garis tempat Anda ingin menemukan / mengganti dalam salah satu mode visual:

  • VISUALmode ( V)
  • VISUAL BLOCKmode ( Ctrl+ V)
  • VISUAL LINEmode ( Shift+ V, berfungsi terbaik dalam kasus Anda)

Setelah Anda memilih baris untuk diganti, ketikkan perintah Anda:

:s/<search_string>/<replace_string>/g

Anda akan perhatikan bahwa rentang '<,'>akan dimasukkan secara otomatis untuk Anda:

:'<,'>s/<search_string>/<replace_string>/g

Di sini '<berarti garis yang disorot pertama , dan '>berarti garis yang disorot terakhir .

Perhatikan bahwa perilaku mungkin tidak terduga ketika dalam NORMALmode: '<dan '>arahkan ke awal dan akhir dari sorotan terakhir yang dilakukan di salah satu VISUALmode. Sebaliknya, dalam NORMALmode, nomor baris khusus .dapat digunakan, yang berarti baris saat ini . Karenanya, Anda dapat menemukan / mengganti hanya pada baris saat ini seperti ini:

:.s/<search_string>/<replace_string>/g

Hal lain yang perlu diperhatikan adalah memasukkan kedua :antara rentang dan perintah find / replace tidak ada salahnya, dengan kata lain, perintah-perintah ini akan tetap berfungsi:

:'<,'>:s/<search_string>/<replace_string>/g
:.:s/<search_string>/<replace_string>/g

1
> Contoh: ganti teks dari baris 6-10, 14-18 tetapi bukan dari 11-13. - bukankah jawaban Anda menjawab pertanyaan ini, bukan?
poige

27

Anda dapat melakukannya dengan dua urutan temukan / ganti

  :6,10s/<search_string>/<replace_string>/g
  :14,18s/<search_string>/<replace_string>/g

Kali kedua yang perlu Anda sesuaikan adalah rentang jadi alih-alih mengetik semuanya, saya akan mengingat perintah terakhir dan mengedit hanya rentang


20

Jika Anda bingung baris mana yang akan terpengaruh, Gunakan di bawah ini

 :%s/foo/bar/gc  

Ubah setiap 'foo' menjadi 'bar', tetapi mintalah konfirmasi terlebih dahulu. Tekan 'y' untuk ya dan 'n' untuk tidak. Jangan lupa menyimpan setelah itu

:wq

1
Anda benar-benar dapat menggunakan cbendera selain menentukan rentang, jadi :6,10s/<search_string>/<replace_string>/cberfungsi. csingkatan confirm. Saya sering menggunakan cbendera untuk mencegah dari penggantian kata-kata yang tidak sengaja di mana saya tidak berpikir bahwa mereka ada di sana juga.
Wolfson

16

VI mencari dan mengganti contoh perintah

Katakanlah Anda ingin menemukan kata yang disebut "foo" dan ganti dengan "bar".

[Esc]Tombol tekan pertama

Ketik: (titik dua) diikuti oleh %s/foo/bar/dan tekan tombol [Enter]

:%s/foo/bar/


11
:%s/<search_string>/<replace_string>/gPerintah Anda akan menggantikan semua kejadian di seluruh file. Bukan jawaban yang tepat untuk pertanyaan itu, tetapi tetap berguna :)
tanius

@ Tanius Sebenarnya itu adalah jawaban paling langsung untuk masalah saya. Anda dapat mempertimbangkan untuk mengubah pertanyaan menjadi "Temukan dan ganti string dalam vim pada baris" Selected "
Omid N

9

Kami tidak perlu repot memasukkan nomor baris saat ini.

Jika Anda ingin mengubah masing foo- masing ke baruntuk baris saat ini ( .) dan dua baris berikutnya ( +2), cukup lakukan:

:.,+2s/foo/bar/g

Jika Anda ingin mengonfirmasi sebelum perubahan dilakukan, ganti gdengan gc:

:.,+2s/foo/bar/gc

Hal baik lain yang sering saya gunakan adalah :.,$s/foo/bar/gcmencari & mengganti mulai dari baris saat ini hingga akhir file.
Wolfson

3

Cari dan ganti

:%s/search\|search2\|search3/replace/gci

g => pencarian global

c => Minta konfirmasi terlebih dahulu

i => Tidak sensitif huruf

Jika Anda ingin penggantian langsung tanpa konfirmasi, gunakan perintah di bawah ini

:%s/search/replace/g

Jika Anda ingin konfirmasi untuk setiap penggantian maka jalankan perintah di bawah ini

:%s/search/replace/gc

Minta konfirmasi terlebih dahulu, di sini pencarian akan menjadi case-sensitive.

:%s/search/replace/gci

1

Menentukan rentang melalui pemilihan visual tidak apa-apa, tetapi ketika ada operasi yang sangat sederhana hanya beberapa baris yang dapat dipilih oleh operator, yang terbaik adalah menerapkan perintah ini sebagai operator.

Sayangnya ini tidak dapat dilakukan melalui perintah standar vim. Anda bisa melakukan semacam solusi menggunakan! operator (filter) dan objek teks apa pun. Misalnya, untuk menerapkan operasi ke paragraf, Anda dapat melakukan:

!ip

Ini harus dibaca sebagai "Terapkan operator! Di dalam paragraf". Operator filter memulai mode perintah dan secara otomatis memasukkan rentang garis diikuti dengan literal "!" Anda dapat menghapus setelahnya. Jika Anda menerapkan ini, ke paragraf berikut:

1
2  Repellendus qui velit vel ullam!
3  ipsam sint modi! velit ipsam sint
4  modi! Debitis dolorum distinctio
5  mollitia vel ullam! Repellendus qui
6  Debitis dolorum distinctio mollitia
7  vel ullam! ipsam
8
9  More text around here

Hasilnya setelah menekan "! Ap" akan seperti:

:.,.+5

Sebagai '.' (titik) berarti garis saat ini, kisaran antara garis saat ini dan 5 garis setelahnya akan digunakan untuk operasi. Sekarang Anda dapat menambahkan perintah pengganti dengan cara yang sama seperti sebelumnya.

Bagian yang buruk adalah bahwa ini tidak mudah untuk memilih teks untuk yang terakhir menerapkan operator. Bagian baiknya adalah ini dapat mengulangi penyisipan rentang untuk rentang teks serupa lainnya (dalam hal ini, paragraf) dengan ukuran yang sangat berbeda. Yaitu, jika nanti Anda ingin memilih rentang paragraf yang lebih besar '.' akan melakukannya dengan benar.

Juga, jika Anda menyukai gagasan menggunakan objek teks semantik untuk memilih rentang operasi, Anda dapat memeriksa plugin saya EXtend.vim yang dapat melakukan hal yang sama tetapi dengan cara yang lebih mudah.


0

Untuk menjawab pertanyaan ini:

:40,50s/foo/bar/g

ganti foo dengan bar di baris ini antara baris ke-40 dan ke-50 (termasuk), saat menjalankan perintah ini, Anda saat ini dapat berada di baris mana saja.

:50,40s/foo/bar/g

juga berfungsi, vim akan meminta Anda untuk konfirmasi dan kemudian melakukan penggantian untuk Anda seolah-olah Anda telah memasukkan perintah pertama.

:,50s/foo/bar/g

ganti foo dengan bar pada baris-baris ini di antara baris Anda saat ini dan baris ke-50 (inklusif). (jika Anda berada dalam garis SETELAH vim garis ke-50 akan meminta konfirmasi lagi)

Untuk memperjelas perbedaan antara vim dan plugin vrapper dari Eclipse:

Perhatikan bahwa dalam varpper

:,50s/foo/bar/g perintah TIDAK akan bekerja.

:50,40s/foo/bar/g akan bekerja tanpa meminta konfirmasi.

(Untuk Versi Vrapper 0.74.0 atau lebih tinggi).


-5
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal

Misalkan jika Anda ingin mengganti yang di atas dengan beberapa info lainnya.

COMMAND(:%s/\/sys\/sim\/source\/gm\/kg\/jl\/ls\/owow\/lsal/sys.pkg.mpu.umc.kdk./g)

Dalam hal ini di atas akan diganti dengan ( sys.pkg.mpu.umc.kdk.).


Saya tidak yakin ini benar-benar menjawab pertanyaan. Dari pertanyaan yang muncul, orang yang bertanya sudah mengetahui bagaimana menggunakan %suntuk memodifikasi input tetapi ingin tahu bagaimana melakukannya "secara semi-global" (yaitu spesifikasinya adalah baris 6-10 dan 14-18 tetapi tidak pada baris 11- 13).
Brandon Buck

1
Apa itu "PERINTAH"? Dan Anda menderita sindrom tusuk gigi yang condong .
Martin Tournoij

Untuk menyembuhkan sindrom itu, Anda dapat menggunakan karakter lain sebagai pembatas bukan default /, misalnya !, @, _::%s_/sys/sim/source/gm/kg/jl/ls/owow/lsal_sys.pkg.mpu.umc.kdk_g
MortezaE
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.