Vim arama, geçerli (proje) klasöründeki tüm dosyaları değiştirir


36

Vim ile ilgili açık sorularımdan biri, şu anki projede bir arama / değiştirme yapmanın bir yolu olup olmadığıdır (başka bir editörden miras kalan bu kavramı kullanırsam bana aittir).

Örneğin, proje dosyalarımda bir yöntem adı aramak istediğimi varsayalım ve bu yöntem çağrısının tüm örneklerini yeniden adlandırın.

Sublime ile böyle devam edebilirim.

görüntü tanımını buraya girin

Bunu Vim'de (muhtemelen MacVim'de) ackveya gibi başka programlara güvenmeden nasıl yaparsınız sed?

Yanıtlar:


35

Bunu yapmanın birkaç yolu vardır.

Geçerli Dizin İçinde

Bir proje ağacında arama / değiştirme yapmak istiyorsanız, Vim'in argüman listesini kullanabilirsiniz .

Basitçe Vim'i açın ve :argsargüman listesini doldurmak için komutu kullanın. Birden fazla dosya isimleri ve hatta globs bile geçebilirsiniz.

Örneğin, :args **/*.rbo anki dizinde ruby ​​dosyalarını tekrar tekrar arayacaktır. Bunun aynı zamanda Vim'i açmak gibi olduğuna dikkat edin vim **/*.rb. findGeçerli dizindeki tüm dosyaların bir listesini çalıştırmak için kabuğun komutunu bile kullanabilirsiniz :

:args `find . -type f`

Mevcut arg listesini :argskendi başına çalıştırarak görüntüleyebilirsiniz . Listeden dosya eklemek veya silmek isterseniz, sırasıyla :argaddveya :argdeletekomutlarını kullanabilirsiniz .

Listeden memnun kaldığınızda, artık Vim'in :argdoargüman listesindeki her dosya için bir komut çalıştıran güçlü komutunu kullanabilirsiniz ::argdo %s/search/replace/g

İşte arama için bazı ipuçları (yorumların bazılarına dayanarak):

  1. Eğer "foo_bar" kelimesini değil, "foo" kelimesini aramak istiyorsanız, sınır kelimesi kullanın. Arama şablonunun etrafındaki \<ve \>yapısını şöyle kullanın ::argdo %s/\<search\>/foobar/g
  2. /cBir arama terimini değiştirmeden önce Vim'in onay istemesini istiyorsanız, bir arama bayrağı kullanın .
  3. /e"Kalıp bulunamadı" hatalarını atlamak istiyorsanız bir arama bayrağı kullanın .
  4. Ayrıca arama yaptıktan sonra dosyayı kaydetmeyi seçebilirsiniz: :argdo %s/search/replace/g | update. Burada, :updateyalnızca değiştirilmişse dosyayı kaydedeceği için kullanılır.

Tamponları aç

Zaten arabellekleriniz açıksa aramayı / değiştirmeyi yapmak istiyorsanız :bufdo, arabellek listenizdeki ( :ls) her dosya için bir komut çalıştıran kullanabilirsiniz .

Komut şuna çok benzer :argdo: :bufdo %s/search/replace/g

Benzer :argdove :bufdovardır :windove :tabdosırasıyla pencereleri ve sekmeleri o hareket. Daha az sık kullanılırlar ancak bilmeleri yararlıdır.


4
/cBayrak değiştirmeyi onaylamak için kullanmak muhtemelen iyi bir fikir olabilir .
romainl

3
Kısmi kelime değişimlerini önlemek için kelime sınırlarını \<ve \>çevresini kullanmanızı tavsiye ederim search.
to to mmcdo

1
Bir diğer yorum ise, vim'in çalışma dizini, mevcut dosyanın dizinini değil, vim'i başlattığınız varsayılan olarak. Çalışma dizinini kullanarak geçerli dosyaya ayarlayabilirsiniz :cd %:p:h. Diğer çalışma dizini seçenekleri vim.wikia.com/wiki/Set_working_directory_to_the_current_file içinde listelenmiştir .
studgeek

28

Diyelim ki böyle basit bir proje yapısına sahibiz:

görüntü tanımını buraya girin

greeting.txt benziyor

görüntü tanımını buraya girin

ve info / age.txt benziyor

görüntü tanımını buraya girin

Sam'in tüm oluşumlarını Bob ile değiştirmek istediğimizi varsayalım. İşte yapacağımız şey:

  1. Çalışma dizinini ayarla

    Vim'in mevcut çalışma dizininin projenin kökü olduğundan emin olun (bunun nasıl yapılacağını size göstermeyecektir).

  2. 'Sam' içeren dosyaları bulun

    Proje içindeki Sam'in tüm oluşumlarını aramak için Vim'in vimgrep komutunu kullanın (not: **/*tüm dosyalarda art arda arama yapar)

    :vimgrep /Sam/gj **/*
    

    Bu, hızlı düzeltme listesini tüm Sam örnekleriyle doldurur. Hızlı düzeltme listesini görüntülemek istiyorsanız, Vim komutunu kullanabilirsiniz.:copen görüntü tanımını buraya girin

  3. 'Sam' içeren tüm dosyaların yerine geç

    Şimdi, hızlı düzeltme listesindeki her dosyanın içine Vim substitute komutunu çalıştırmak istiyoruz. Bunu :cfdo {cmd}, quickfix listesindeki her bir dosyada {cmd} 'yi çalıştıran komutu kullanarak yapabiliriz . Kullanmak istediğimiz belirli {cmd} substituteveya skısa. Tam çizgi şöyle olurdu:

    :cfdo %s/Sam/Bob/g
    

    İsterseniz tüm değiştirmeleri onaylamak için c bayrağını ekleyebilirsiniz:

    :cfdo %s/Sam/Bob/gc
    
  4. Tüm dosyaları kaydet

    :cfdo update
    

2
Bunu daha çok seviyorum. Çok basit ve Ack (veya QuickFix penceresini dolduran herhangi bir eklenti) ile çalışır.
Zuhaib

1
Bu büyük bir cevaptır
Peoplein

2
“Son değişiklikten bu yana yazma yok” muydu, cfdo %s/Sam/Bob/g | updatebenim için düzeltti
hakunin

@hakunin Henüz yapmadıysanız, hiddenseçeneği ayarlamanızı tavsiye ederim :set hidden.
Niko Bellic

3

Bir VIM çözümü olmasa da, VI / VIM kullanıyorsanız, bir CLI çözümü kullanmayı daha kolay bulabilirsiniz. Geçerli dizindeki tüm dosyaları değiştirmek için perl, bu gibi durumlarda yapıldığı gibi kullanın :

$ perl -pi -e 's/foo/bar/g' *

Eğer çok alt dizinleri bunu yapmak gerekirse, ben genellikle eşleştirmek perlile find:

$ find . -name '*' -print0 | xargs -0 perl -pi -e 's/foo/bar/g'

Bununla ilgili güzel bir şey, listeyi belirli dosya türlerine göre daha da hassaslaştırabilmenizdir. Örneğin, python dosyalarını kısıtlamak için:

$ perl -pi -e 's/foo/bar/g' *.py
$ find . -name '*.py' -print0 | xargs -0 perl -pi -e 's/foo/bar/g'

1

İfadeyi bir diğeriyle değiştirmek için, Vim Ex modunu kullanabilirsiniz.

Örneğin ( extakma addır vim -E):

$ ex -s +'bufdo!%s/foo/bar/g' -cxa *.*

Tekrarlı bash / zsh cinsinden ( globstarörneğin set ile shopt -s globstar):

$ ex -s +'bufdo!%s/foo/bar/g' -cxa **/*.*
$ ex -s +'n **/*.*' +'bufdo!%s/foo/bar/g' -cxa

Tekrarlı olarak ( finddosyalar gibi gizli dosyaları kullanarak ve görmezden gelin .git):

$ find . -type f -not -path '*/\.*' -exec ex -s +'bufdo!%s/foo/bar/g' -cxa {} "+"

Not: :bufdoKomut POSIX değil .

Not: Sözdizimi -not -path '*/\.*', gizli dosyaları (örneğin .git) yoksaymak için kullanılır .



0

Burada findve kullanarak ex( kullanmadan:bufdo ) editörü shell komutudur :

find . -name '*.rb' -exec ex +'%s/foo/bar/ge' -V1 -scwq! {} ';'

Bu irade düzenlemek tümünde-yerleştirmek *.rbgeçerli klasöre (yinelemeli) dosyaları ve değiştirme fooile bar.

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.