Saya punya file XML besar
<obj param="2542">
<obj param="2333">
<obj param="6433">
Saya perlu meningkatkan semua nilai "param" dengan beberapa angka. Saya dapat mencocokkan angka yang saya butuhkan dengan pencarian regexp di banyak editor, tetapi bagaimana cara menerapkan beberapa matematika pada pengganti?
search
text-editors
regex
serg
sumber
sumber
vim
danemacs
bisa melakukan hal semacam ini, tetapi mungkin perlu menulis skrip daripada menggunakan satu perintah.Jawaban:
Setelah sedikit lebih bolak-balik, ternyata vim bisa melakukannya dengan satu perintah, tanpa scripting. Misalnya, untuk menambahkan 50 ke semua angka berikut
<obj param="
Anda dapat menggunakan::%s@<obj param="\(\d\+\)@\='<obj param="' . (submatch(1) + 50)@g
Biarkan saya memecahnya.
:
adalah cara umum untuk masuk / menandakan mode baris perintah di vim.%
berarti dalam lingkup seluruh dokumen; Anda bisa memasukkan rentang angka, misalnya,1,50
hanya melakukannya dalam 50 baris pertama saja.s
adalah singkatan untuk pengganti (Anda dapat menulis seluruh kata jika Anda suka)@
adalah pembatas; Anda dapat menggunakan karakter lain selama tidak dalam apa yang Anda cari. Cukup gunakan tiga kali. (Sintaksnya mirip dengansed
.)Semuanya hingga kemunculan pembatas @ berikutnya adalah pola reg ex untuk dicari, dalam hal ini
<obj param="
diikuti oleh\d\+
, yang merupakan angka berapa pun. The\(
dan\)
ada di sana untuk mengatur seluruh urutan digit ini sebagai grup reg ex tunggal yang akan cocok dengan referensi seperti\1
, atausubmatch
perintah vim .Kemudian pembatas
@
menandai bahwa apa yang mengikuti sebagai teks pengganti.Di
\=
bagian awal di sini berarti menggantikan hasil dari beberapa ekspresi yang dievaluasi, bukan pola atau string reg ex, yang merupakan kunci di sini.Kemudian kita miliki
'<obj param="'
untuk memulai teks pengganti. The.
yang mengikuti adalah fungsi vim untuk concatenating string.submatch(1)
adalah fungsi built-in vim yang hanya dapat digunakan dalam perintah substitusi, dan mengembalikan string yang sama dengan regex\1
; Anda akan menggunakansubmatch(2)
setara dengan regex\2
dan sebagainya. (\0
adalah seluruh pola yang cocok, tetapi kami tidak ingin itu ada di sini.)\(
Dan\)
dalam pola pencarian digunakan untuk menandai apa yang dianggap sebagaisubmatch(1)
.Oleh karena itu
(submatch(1) + 50)
berikan hasil menambahkan 50 ke angka yang diikuti digit<obj param="
dalam bentuk pola pencarian.Pembatas
@
lagi digunakan untuk menandai akhir teks pengganti.Bendera
g
digunakan untuk membuat pergantian global; Anda bisa menghilangkan ini jika Anda hanya ingin mengganti instance pertama pada setiap baris.Anda mungkin dapat bekerja dari sana cara menambahkan angka yang berbeda, atau mengurangi, atau membagi, dll.
sumber
Di Emacs (sejak versi 23): gunakan
\,
untuk mengeksekusi kode Lisp sewenang-wenang dalam penggantian regexp . Misalnya, untuk menyamakan angka yang bisa Anda gunakanDi Vim: mulai teks pengganti Anda dengan
\=
(lihat:help sub-replace-special
). Misalnya, untuk menyamakan angka:Beberapa editor memungkinkan Anda untuk melakukan hal-hal semacam ini dengan makro: tentukan makro yang 1. mencari kecocokan berikutnya dan 2. melakukan penggantian (menggunakan alat eksternal untuk aritmatika jika perlu); ulangi makro sebanyak yang Anda cocok.
sumber
Anda dapat menggunakan vim untuk melakukannya untuk Anda. Cukup buka file Anda dan rekam makro . Contoh: Cari nomor apa saja
lalu tekan q dan a (simpan makro di register a). Setelah itu, tekan Ctrl-X (menambah angkanya 1) dan tekan n (untuk hasil pencarian selanjutnya) sesudahnya. Setelah Anda melakukannya, tekan q lagi untuk menyimpan makro. Sekarang Anda dapat menerapkan makro ke nomor berikutnya dengan menekan @ + a. Ini akan mengubah angka saat ini dan melompat ke yang berikutnya. Dengan mengulanginya atau menggunakan x @ a, Anda dapat mengulanginya x kali.
Yah, deskripsi itu mungkin tidak cukup untuk menunjukkan bagaimana hal itu bisa dilakukan. Lihat saja tutorial yang menjelaskan mekanisme makro di vim.
sumber