Yeni metne matematik uygulayabilen herhangi bir metin editörü var mı?


15

Büyük XML dosyam var

<obj param="2542">
<obj param="2333">
<obj param="6433">

Tüm "param" değerlerini bir miktar arttırmalıyım. Birçok editörde regexp arama ile ihtiyacım olan sayıları eşleştirebilirim, ancak değiştirmeye nasıl matematik uygulanır?


1
Hangi işletim sistemi? Bunun yerine bir kabuk komut dosyasından memnun olur musunuz (oldukça kolay olurdu)? Her neyse, eminim vimve emacsbu tür bir şey yapabilirim, ancak tek bir komut kullanmak yerine bir komut dosyası yazmayı gerektirebilir.
frabjous

@frabjous pencerelerin altında. Mümkünse hiçbir şey yazmamayı tercih ederim. Ancak bir kabuk betiği yayınlarsanız, birçok kişi için yararlı olacağından eminim.
serg

Yanıtlar:


18

Biraz daha etrafta dolaştıktan sonra, vim'in komut dosyası olmadan tek bir komutla yapabileceği ortaya çıkıyor. Örneğin, aşağıdaki tüm sayılara 50 eklemek için şunu <obj param="kullanabilirsiniz:

:%s@<obj param="\(\d\+\)@\='<obj param="' . (submatch(1) + 50)@g

Bırakın onu yıkayım.

: vim'de komut satırı moduna girmenin / göstermenin genel yoludur.

%tüm belgenin kapsamında anlamına gelir; bir sayı aralığına koyabilirsiniz, örneğin, 1,50bunu sadece ilk 50 satır içinde yapmak için.

s yerine kısayol (tercih ederseniz tüm kelimeyi yazabilirsiniz)

@sınırlayıcı; aradığınız şeyde olmadığı sürece başka bir karakter kullanabilirsiniz. Sadece üç kez kullanın. (Sözdizimi şuna benzer sed.)

Sınırlayıcı @ 'ın bir sonraki oluşumuna kadar her şey, bu durumda, <obj param="ardından \d\+herhangi bir sayı basamağı aranacak reg ex modelidir . \(Ve \)tek reg ex gibi geribaşvuruları eşleşir grup olarak rakam tüm bu diziyi orada ayarlamak için vardır \1, ya Vim submatchkomutu.

Daha sonra sınırlayıcı @, yerine geçen metni izler.

Buradaki \=başlangıç, burada anahtar olan reg ex paterni veya dizesi yerine değerlendirilmiş ifadenin sonucunu ikame etmek anlamına gelir.

Sonra '<obj param="'yedek metnin başlangıcı var . .Aşağıdaki hangi dizeyi birleştirmekten için Vim fonksiyonudur.

submatch(1)yalnızca bir ikame komutu içinde kullanılabilen ve regex ile aynı dizeyi döndüren bir vim yerleşik işlevidir \1; submatch(2)regex'ler ve benzeri eşdeğeri için kullanabilirsiniz \2. ( \0eşleşen tüm modeldir, ancak bunu burada istemiyoruz.) Arama modelinde \(ve \)içindeki sayıları işaretlemek için kullanılır submatch(1).

Bu nedenle , arama deseni formunda (submatch(1) + 50)takip eden rakamlara 50 eklenmesinin sonucunu verir <obj param=".

Sınırlayıcı @, değiştirilen metnin sonunu işaretlemek için tekrar kullanılır.

Bayrak g, oyuncu değişikliklerini global yapmak için kullanılır; yalnızca her satırdaki ilk örneği değiştirmek istiyorsanız bunu atlayabilirsiniz.

Muhtemelen oradan nasıl farklı numaralar ekleyeceğinizi, çıkarabileceğinizi veya ayırabileceğinizi vb.


Bu harika, boylam değerleri tamamen geçersiz olduğu için bozuk bir GPX dosyası vardı. Neyse ki, enlem tamam oldu, bu yüzden bir harita kullanarak ilk doğru değerin ne olması gerektiğini çalıştırabildim, bazı matematikler yapabildim ve doğru yapmak için her değerden 4294.567548 çıkarmak zorunda kaldım. Sahip olduğum tek engel, bu yöntemin bir kayan nokta sayısı üzerinde çalışmadığıydı, bu yüzden ondalık noktanın her iki tarafını da ayrı ikameler olarak yaptım, bir -4294 ve bir -567548.
stuffe

7

Emacs'te (sürüm 23 ve beri): kullanım \,keyfi Lisp kodu çalıştırmak için regexp'in değiştirilmesi . Örneğin, kullanabileceğiniz sayıların karesini almak için

M-x replace-regexp
param="\([0-9]+\)"
param="\,(* \#1 \#1)"

Vim'de: değiştirme metninizi \=(bkz. :help sub-replace-special) İle başlatın . Örneğin, sayıların karesini almak için:

s!param="\([0-9]\+\)"!\='param="'.submatch(1)*submatch(1).'"'!

Birkaç editör, bu tür şeyleri makrolarla yapmanıza izin verir: 1. bir sonraki eşleşmeyi arayan ve 2. yerine geçen bir makroyu tanımlayın (gerekirse aritmetik için harici bir araç kullanarak); makroyu eşleşmeleriniz kadar tekrarlayın.


Yetersiz cevap. Kısa ve 2 editör + genel durum.
derekv

1

Bunu yapmak için vim kullanabilirsiniz. Sadece dosyanızı açın ve bir makro kaydedin . Örnek: Herhangi bir numarayı arayın

/[0-9]{1,}

sonra q ve a tuşlarına basın (makroyu a kaydında sakla). Bundan sonra, Ctrl-X (sayıyı 1 arttırmak) ve ardından n (sonraki arama sonucu için) tuşuna basın. Bunu yaptıktan sonra, makroyu kaydetmek için tekrar q tuşuna basın. Şimdi @ + a tuşlarına basarak makroyu sonraki sayıya uygulayabilirsiniz. Bu, geçerli numarayı değiştirir ve bir sonraki numaraya atlar. Bunu tekrarlayarak veya x @ a kullanarak, x kez tekrarlayabilirsiniz.

Bu açıklama, nasıl yapılabileceğini göstermek için yeterli olmayabilir. Vim'deki makro mekanizmasını açıklayan bir eğiticiye bakın.


Numarayı 1 değil milyonda değiştirmem gerekirse ne olur? Veya bazı çarpma / bölme kullanın?
serg

1
Her sayıya sabit bir x eklemek istiyorsanız kolaydır: x + Ctrl + a. Farklı numaralar mı eklemeniz gerekiyor?
evnu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.