Dosyadan iki desen arasındaki içerik nasıl değiştirilir?


9

Aşağıdaki dosya biçimim var:

<common>
fitnes=0
genetic=1
method=0
</common>
<inputs>
foo=bar
bar=foo
</inputs>
<limits>
balance=200.00
</limits>

ve ben arasında ne silme şeyi istiyoruz <inputs>ve </inputs>(o-self desen hariç) ve başka bir dosyadan (örn gelen içerik ile değiştirin foo.txt). Başka bir deyişle, satırlar başka bir içerikle yer değiştirir foo=barve yer bar=foodeğiştirilir.

Muhtemelen, çok satırlı bir eşleşmeyi nasıl sildiğinize benzer , örneğin:

:g/<inputs/,/inputs>/d

ancak başka bir dosyanın içeriğini eklemek için neyi değiştirmem gerektiğinden emin değilim d, ancak eşleşen kalıbı korumak istiyorum.

Benzer bir yaklaşım olacaktır html etiketi iç içeriği kaldırmak gibi

:/<inputs>/norm vitd

ama sonra dosyadaki içeriği nasıl ekleyeceğinizi bilmiyorum.

İdeal olarak, bir liner bulmaya çalışıyorum, çünkü başka bir komut dosyasının parçası olacak.

Bunu nasıl başarabilirim?

Yanıtlar:


10

Bir kalıbı aşağıdaki gibi bir ifadenin sonucuyla değiştirmek için bir ikame kullanılabilir:

:keeppatterns %s;<inputs>\zs\_.\{-}\ze</inputs>;\=insert(readfile('test.txt'), '')

Görmek :help sub-replace-expression

Not olduğunu keeppatternsönler substitutearama geçmişi ve koruyan "Son arama desen kayıt" bir şey eklemesini komut - bkz :help "/. Bu gereksiz komut değiştiricileri ile Vim'ın küresel durumunu değiştirmesini komut dosyalarını engellemek için iyi bir uygulamadır keepalt, keepjumps, lockmarks, keepmarks, ve keeppatterns.


5

Gary'den buna alternatif bir yaklaşım şudur:

:g/^<inputs>/+,/^<\/inputs>/-d|-r dummy

Hangi ilk önce verilen desen her şeyi siler, :rkukla dosyadan veri okumak için komutu kullanır . Şimdi dosya <input>/</input>adını desen arasındaki satırlardan çıkarmanız gerekiyorsa , biraz daha karmaşık hale gelir.


4

Bu en azından bir Unix sisteminde işe yarıyor gibi görünüyor:

:/<inputs>/+1,/<\/inputs>/-1!cat foo.txt

Bu kullanan {range}!{filter}ardına gelen satırları filtre komutu <inputs>önce birine </inputs>dış program ile cat foo.txt. Bu durumda, catstandart girişini yoksayar, böylece orijinal satırlar silinir ve dosyanın içeriği ile değiştirilir foo.txt.

Görmek:

:help :range!
:help cmdline-ranges

2

Bir makronun daha kolay bir yaklaşım olacağını hissediyorum. Özellikle, aynı şeyi yapmak için çeşitli yerleriniz varsa.

  1. Yalnızca bu 2 dosyayı açık tutun.
  2. Şimdi ilk dosyada ile kaydetmeye başlayın qa,( akayıt adıdır).
  3. Başlangıç ​​desenini arayın, aşağı basın , ardından Ctrl- düğmesine basın v, bitiş desenini arayın, yukarı basın . Şimdi silmek istediğiniz bölüm seçildi. Silin.
  4. Kullanarak konumunu işaretleyin ma( aişareti adıdır) ve dosyayı kaydedin.
  5. :b2Komut ile 2. dosyaya gidin ve benzer şekilde başlangıç ​​/ bitiş kriterlerinize göre parçayı seçin.
  6. Bu dosyaya geri dönün ao noktaya gitmek için basın . Oraya yapıştırın p.
  7. Son ölçütleri tekrar arayın ve tekrar çarpmamak için bölümü çaprazlayın.
  8. Tuşuna basarak kayıt işleminden çıkın q.
  9. Sayısını tekrarlayın 40@a.

1
Öneri için teşekkürler, iyi, ama bu özel durumda yardımcı olmayacaktır, çünkü exkomut dosyası olarak kullanıcı giriş argümanlarına bağlı olarak hangi dosyayı eklemek için belirtebilirsiniz etkileşimli olmayan bir çözüm arıyorum .
kenorb

1

Bu, XML'i XML olmayan Araçlar ile ayrıştırmak için başka bir girişim ise yapmayın.

Buradaki çözümler geçerlidir, ancak amaç olmayabilir. XML iyi evcilleştirilmiş bir kaynaktan değilse, etikette kaçışlar, CDATA veya beyaz boşluklar alabilirsiniz!

Yani vi komutundan xsltproc bununla başa çıkabilir.


Dosya aslında uygun XML formatı değil, aslında bu 3 XML benzeri etikete sahip iyi belgelenmiş bir inidosya değil .
kenorb
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.