find: kuru erik belirtilen yolu görmezden gelmez


13

Aramamın .gitdışında bırakmam gerekiyor find. Bunu başarmak için -path ./.git -pruneanahtarı kullanıyorum :

$ find . -path ./.git -prune -o \( -type f -o -type l -o -type d \) | grep '.git'
./.git

Ancak, bu .git dizininin içeriğini atlasa da dizinin kendisini listeler. Eklediğimde çalışıyor-path ./.git -prune -o -print -a

find . -path ./.git -prune -o -print -a \( -type f -o -type l -o -type d \) | grep '.git'

Bu neden gerekli. Her iki komutun da aynı çıktıya sahip olması gerektiğini düşündüm. İkinci sözdizimi oldukça çirkin.


4
İhtiyacınız olan -print, aksi takdirde örtük -printdurumun tamamı için geçerlidir
Stéphane Chazelas


Yanıtlar:


3

manİçin sayfa findverir:

-prune True; if the file is a directory, do not  descend  into  it.  If
      -depth  is  given,  false;  no  effect.  Because -delete implies
      -depth, you cannot usefully use -prune and -delete together.

Dolayısıyla ilk örnekte bu doğru değildir -path ./.git -pruneve bu nedenle varsayılan eylem ( -print) çağrılmaz, böylece satır yazdırılır.


22

Budanan dizinlerin neden findkomut tarafından yazdırıldığına ve nasıl -pruneçalıştığına dair diğer bazı karmaşık ayrıntılara neden şaşırdım , ancak birkaç örnekle anlayabildim.

Aşağıdaki örnekleri çalıştırmak için aşağıdaki dizinleri ve dosyaları oluşturun.

mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3

Bu yapıyı oluşturmak için:

$ tree

.
├── aa
   └── file1
├── bb
   └── file3
└── file1

Şimdi adlı dizinleri aramak için find komutunu kullanın aa. Burada sorun yok.

$ find . -type d -name aa
./aa

Aa dışındaki tüm dizinleri arayın ve geçerli dizini aldık .ve ./bbbu da mantıklı.

$ find . -type d ! -name aa
.
./bb

Şimdiye kadar iyi, ama kullandığımızda -prunefind budama yaptığımız dizini döndürür, bu da başlangıçta beni şaşırttı çünkü budama değil diğer tüm dizinleri döndürmesini bekliyordum.

$ find . -type d -name aa -prune
./aa

Değil de, açıklanmıştır budanmış olan dizini döndürür sebebi -prunebelirtildiği gibi adam sayfalarının bölümünde Timo cevap ama, EXPRESSIONSbölüm:

İfadesi dışında hiçbir eylemleri içeriyorsa -prune,  -printifade doğru olduğu tüm dosyalarda yapılır.

yani ifade aadizin adıyla eşleştiği için ifade true olarak değerlendirilir ve find dolaylı -printolarak tüm komutun sonuna örtülü olarak a eklediğinden yazdırılır . Bu bir eklemez -printsen bilerek eylemi eklerseniz, ancak, -o -printsonuna kendiniz için:

find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3

Burada find komutu -printartık örtük DEĞİLDİR ve bu yüzden budama ( aa) dizini yazdırılmaz.

Son olarak, dosya adı deseninden file*sonra olan dosyaları arayan bir cümle eklersek -o, o zaman -printbu ikinci cümlenin sonuna bir a koymanız gerekir :

find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3

Bunun çalışmasının nedeni aynıdır: -printİkinci fıkra içine a koymazsanız , eylem dışında bir işlem olmadığından -prunefind -printkomutun SONUNDA otomatik olarak ekleyerek -prunecümlenin budanmış dizin:

find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3

Genel olarak, -printkomutu ikinci maddeye yerleştirmeniz gerekir . Orijinal posterin yaptığı gibi ortaya koyarsanız, düzgün çalışmaz, çünkü budama dosyaları hemen yazdırılır ve ikinci fıkra istediği dosyaları seçme şansı elde etmez:

find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3

Ne yazık ki, orijinal poster yukarıdaki komutu yanlış yere yerleştirerek -printyanlış verdi. Özel davası için işe yaramış olabilir, ancak genel durumda işe yaramaz.

Nasıl -pruneçalıştığını anlamakta zorluk çeken binlerce insan var . findAdam sayfası bu komutla ilgili bitmeyen dünya çapında karışıklığı önlemek için güncellenmelidir.


Adam sayfam (Arch Linux, find-4.6.0), "Tüm ifade -prune veya -print dışında bir eylem içermiyorsa, -print tüm ifadenin doğru olduğu tüm dosyalarda gerçekleştirilir." Ama tarif ettiğin gibi çalışıyor.
x-yuri

0

dan mansayfasında

Tüm dizin ağacını yoksaymak için, ağaçtaki her dosyayı denetlemek yerine -prune komutunu kullanın. Örneğin, src / emacs dizinini ve altındaki tüm dosyaları ve dizinleri atlamak ve bulunan diğer dosyaların adlarını yazdırmak için şöyle bir şey yapın:

find . -path ./src/emacs -prune -o -print

Yani, kullanabilirsiniz:

find . -path ./.git -prune -o -print

Bu, .gitdizini listelemez .

bir dosya adını belirtmek için aşağıdakileri yapabilirsiniz:

find . -path ./.git -prune , -name filename

Lütfen ,virgül operatörüne dikkat edin .


-1

İşte hızlı ve kirli bir alternatif:

find | fgrep -v /.git

Ben sadece findkarmaşık sözdizimini hatırlayamıyorum ...

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.