Her satırdaki son “1” değerini 2-12 arasında artırarak her satırı 11 kez kopyalama


9

Bir dosyada birkaç satır var ve her satırı 11 kez kopyalamak istiyorum (her satırı 12 satıra çevirerek) ve her satırda son "1" 'i artırmak, böylece 12 satır "1" ile " 12 ", burada" 1 "başlangıçta idi. Her satırda başka "1" oluşumları olabilir, ancak artırmak istediğim "1" her satırdaki son olay olacaktır. Buna bakmanın bir başka yolu da, son "1" in "/ nt /" - her zaman "/ nt / 1" 'de olduğu gibi olmasıdır (ve her satırda daima "/ nt / 1" in tek oluşumu olacaktır) .

Yani, örneğin, eğer varsa:

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

Bunu dönüştürmek istiyorum:

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
...

Daha önce komutu bulmuştum:

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

Bu amaçla çalışır, ancak her satır için bu komutu el ile çalıştırmak ve her satırı kendim yazmak (veya kopyalayıp yapıştırın) gerekir. Zaten dosyada bulunan satırları almanın ve açıkladığım şekilde her satırı on iki haline getiren bir komut çalıştırmanın bir yolu var mı?

Bu konuda bana yardımcı olabilecek herkese şimdiden teşekkürler. Ayrıca, buradaki ikinci sorum olduğunu da belirtmek istedim ve en çok minnettar olduğum ilk sorum için birkaç hızlı ve etkili çözüm elde etmekten memnun oldum.

Yanıtlar:


8

İşte sorunu çözen bir ikame:

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

İkame "1" içeren her satırla eşleşir ve metni son "1" den önce {c1}ve sonra yakalar {c2}. Herbir uygun hattı için, on iki birinden sayı aralığı {n}vardır eşlenen formunun on iki hatları oluşturmak için {c1}{n}{c2}. On iki satırdan oluşan her grup, ilişkili, orijinal olarak eşleşen satırın yerini alır.

Bkz :h sub-replace-expression.


2
Vay canına, tek satırlık harika bir komut. Birkaç hafta önce sorduğum ilk soru için tek satırlık zarif bir çözüm bulduğunuzu hatırlıyorum. Güzel iş. Çok teşekkür ederim. Ayrıca, yukarıdaki satırın tamamını yazmadan (veya önceki komutlar listesinde gezinmek zorunda kalmadan) hatırlaması kolay bir komut veya işlev yürütebilmem için _vimrc dosyasına koymanın bir yolu olduğunu tahmin ediyorum, ancak Henüz nasıl yapılacağını bilmek için _vimrc sözdizimine yeterince aşina değilim.
ablewasiereisawelba

10

Bunu şu şekilde yapabilirsiniz

  1. bir makro kaydettikten sonra
  2. globalex komutunu kullanarak makroyu n dosyadaki her satır için n kez çalıştırın .

Makroyu kaydettikten sonra, kayıt sırasında yapılan değişiklikleri geri alın, yoksa ilk satır için n + 1 ek satır ve ardışık satırlar için n olacaktır.

Makroyu akayıt defterine kaydedin.

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

Bu aşağıdaki komutu register a( qa...q) içine kaydeder :

  • yyp: geçerli satırı kopyala
  • $: satır sonuna git
  • ?\d<CR>: tek bir basamak için geriye doğru arama
  • <C-A>: imlecin altındaki rakamı bir arttır

Makro kaydedildiğinde, geri alırken ( uu) veya geçerli satırı ( dd) silerek kaydederken yapılan değişiklikleri kaldırın . Ardından 11, global komutla dosyadaki her satır için makro (veya herhangi bir sayıda) kez tekrarlayın :

:g//normal 11@a

2
İşe yaradı! Çok güzel teşekkür ederim. Başlangıçta Ctrl-a eklemek yerine her şeyi vurgulayan bir sorun vardı, çünkü Windows'ta gVim kullanıyorum ... ama hızlı bir arama yaptım ve bu konuyu buldum - stackoverflow.com/questions/289681/… - nerede ben toplama ve çıkarma için "+" ve "-" tuşlarını kullanabilmem için _vimrc içine nnoremap <kPlus> <Ca> nnoremap <kMinus> <Cx> koyma önerisini kullandı. Ayrıca, küresel komutun benim için olması gerekiyordu: g // normal 11 @ a, ama bu kolayca anlaşıldı. Teşekkür ederim!
ablewasiereisawelba

6

İki yol:

Bir makro kullanın!

İle başlayan

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

İmleciniz ilk satırdayken

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

Hangisi:

qq Q kaydına makro kaydetmeye başlayın

yyp geçerli satırı çek ve aşağıya yapıştır

$?\d<CR> Satırın sonuna git ve geriye doğru bakan ilk haneyi bul

<Ctrl-a> Sayıyı artır

q Makroyu kaydetmeyi durdurun.

Bu sizi şöyle bırakır:

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

İmleç ikinci satırdayken. Bu makroyu istediğiniz kadar tekrarlayın (Örneğin, 10 @ q ile on kez tekrarlayın). Bu işlemi her satır için otomatikleştirmek istiyorsanız, her satırda global olarak yürütün:

:g//normal 11@q

Alternatif olarak, daha yeni bir vim sürümü ile: İstediğiniz satırı birçok kez yapıştırın, görsel blok artırmak istediğiniz basamağı seçin ve tuşuna basın g <Ctrl-a>. Bu, görsel bloktaki tüm sayıları istediğiniz gibi arttırmalıdır. Ancak bu daha manuel bir süreçtir.


1
Harika, g <c-a>yolu bilmiyordum . Paylaşım için teşekkürler.
kba Monica ile

1
@fruglemonkey Cevabınızın ilk kısmı yukarıdaki ile aynı, ancak yine de teşekkür ederim. İkinci kısım, benim için işe yaradığını sanmıyorum (yanlış bir şey yapmadıkça), bu yüzden doğru sürümü kullanmamalıyım.
ablewasiereisawelba

5

Bunun gibi tek adımlık görevler için makroları kullanmanın en kolay yolunu buluyorum. Sadece q+ kayıt adıyla bir makro kaydetmeye başlayın ve görevi bir kez yapın. Burada tekrarlanabilir bir görev görüyorum:

  • Hattı seçin
  • çekmek
  • Yapıştır (sizi bir sonraki satıra koyacaktır)
  • satır sonuna git
  • bir kelime geri git
  • bir artış

Şimdi anormal modda kaydetmek için gerekli tuş vuruşlarını kaydedin :

qayyp$b<c-a>.

Makroyu 11 kez yürütmenin bir satır için doğru sonucu verip vermediğini test etmek için satırı tekrar silin:

11@a

Öyle! Şimdi tekrar geri alalım ve tüm süreci ikinci bir makroda otomatikleştirelim b:

qb11@aj

Artık @bdosyanın sonuna kadar çalıştırabilirsiniz ve istediğiniz çıktıyı üretmelidir. Kulağa karmaşık geliyor, ancak tipik düzenleme desenlerine alıştıktan sonra gerçekten değil.


Yanlış bir şey yapıp yapmadığımdan emin değilim, ama işe yaramıyor gibi görünüyor. Yazdıklarını takip ettim, ama belki bir şeyi yanlış anladım ya da düzgün bir şekilde yürütmedim. (Satırın ilk sayısını artırıyorum, satırın son sayısını değil.) Yanıtladığınız için teşekkür ederim.
ablewasiereisawelba

3
İlk makronun olması gerektiğini düşünüyorum qaVyp$b<c-a>. Ya da daha iyisi, sadece qayyp$b<c-a>.
Karl Yngve Lervåg

1
Teşekkürler, @ KarlYngveLervåg, haklısın, makroyu düzelttim.
kba Monica ile

2
. Kapsamlı @ablewasiereisawelba olduğu için Argh :( teşekkürler ben makro tahmin qqyyp$?\d<CR><Ctrl-a>q@fruglemonkey tarafından ve @jjaderberg son numarayı arar beri için tamlık değiştireceğiz iyidir..
kba Monica ile duruyor

2
@kba Sadece birileri sorumu cevaplamak için zaman ve çaba harcarsa, en azından çözümünü deneyebilirim - başka birinden zaten çalışan bir çözüm bulmuş olsam bile. Çabalarınızı takdir ediyorum - ve eğer sizi daha iyi hissettirirse, hala benden kilometrelerce ilerisin. :)
ablewasiereisawelba

2

Aşağıdaki makroyu kaydedin ve her satır için kullanın:

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

Diğer cevaplara göre temel fark, bunun g<C-a>her satırı farklı bir sayı ile artıran bir sütun seçiminde kullanılmasıdır. :help v_g_CTRL-ADaha fazla bilgi için kontrol edin . Ayrıca \zs, imlecin aramadan sonraki numarada durması için desen başlangıç ​​konumunu seçmek için kullandım .

Bunun çalışması için Vim'in son bir sürümüne ihtiyacınız olduğunu lütfen unutmayın.


1
@fruglemonkey de bunu önerdi . Henüz tüm dağıtımlara gönderilmeyen 7.4.754'ten beri oldukça yeni olmasına rağmen (vim standartlarına göre) harika bir özellik.
kba, Monica ile

Özür dilerim
Vitor

1
@Vitor Sadece gVim 7.4 var, bu yüzden bunu g<C-a>@fruglemonkey yapabileceğimi sanmıyorum ve bahsetmiştiniz, ancak cevap verdiğiniz için teşekkürler. Makronuzu denerken - g<C-a>bölüme gelmeden önce , blok vurgulanan artışın peşinde olduğum "1" karakteri değil, bunun yerine ilk karakterdir "1 msgstr "" "blok vurgulanmış karakter. (Ayrıca, toplamda 12 satır eklemek istiyorum çünkü - olurdu yy11pve 10jmakroda olacağını düşünüyorum .) Toplam 12)
ablewasiereisawelba

1
Geri bildiriminiz için teşekkürler. Cevabı buna göre güncelledim. Kullanım karar verdi \zs, ama sadece de sadece bir ilave olabilirdi lSONRA <CR>.
Vitor

1
Muhtemelen vimrc'nizde normal ifade aramasını etkileyen bazı ayarlarınız var. Vim ile başlayarak tekrar deneyin vim -u NONE. Sadece yaptım ve bu mükemmel çalışıyor! Aslında, aramanın ilk 1 ile eşleşmesi mümkün değildir, çünkü önceki eğik çizgiyi gerektirir.
Vitor
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.