Joker karakter gömülü bir “find” aramasında gizli dosyalar ve dizinler nasıl dışlanır / yoksayılır?


119

'Dan başlayarak ( "bazı metinlerden" önce ve sonra joker karakterlere dikkat edin )

find . -type f -name '*some text*'

Kişi tüm gizli dosyaları ve dizinleri nasıl dışlayabilir / yok sayabilir?

Zaten çok uzun zamandır googling yapıyorum , bazı -prune ve! (ünlem işareti) parametreleri, ancak sadece işe yarayan herhangi bir uydurma (ve cimri) örneği yoktur .

Boru | için grepbir seçenek olacaktır ve ben de bunun örneklerini hoşuma gider; ama öncelikle ben kısa bir-liner (veya tek başına biri gömlekleri bir çift, aynı komut satırı hedefe ulaşmak için farklı yollar gösteren) ilgilendiğim sadece kullanarak find.

ps: Linux'ta dosyaları bulun ve belirli dizinleri hariç tutun, birbiriyle yakından ilişkili görünüyor, ancak a) henüz kabul edilmedi ve b) ilgili ancak farklı ve farklı bir konu var, ancak c) ilham verebilir ve karışıklığı tam olarak belirlemeye yardımcı olabilir!

Düzenle

find . \( ! -regex '.*/\..*' \) -type f -name "whatever", Eserleri. Regex "bir şey, sonra bir eğik çizgi, sonra bir nokta, sonra bir şey" (yani alt klasörleri de dahil olmak üzere tüm gizli dosya ve klasörler) ve "!" regex'i olumsuzlar.


: Eğer düzenleme içinde ne sordu yardımcı ama burada sorumu bakmak ve onun cevabı alamaz mı unix.stackexchange.com/q/69164/15760 da cevap bağlantıyı ve.

Yanıtlar:


134

Bu, gizli dosya ve dizinleri atlayarak dizininizin soyundan gelen tüm dosyaları yazdırır:

find . -not -path '*/\.*'

Bu nedenle some text, adına sahip bir dosya arıyorsanız ve gizli dosyaları ve dizinleri atlamak istiyorsanız, şunu çalıştırın:

find . -not -path '*/\.*' -type f -name '*some text*'

Açıklama:

-pathOpsiyon denetler tüm yol dize karşı bir desen çalışır. *joker karakter, /dizin ayırıcı, \.nokta (özel anlamdan kaçınmak için kaçması gereken) nokta ve *başka bir joker karakter. -notbu teste uyan dosyaları seçmeyin.

findÖnceki komutta gizli dizinleri tekrar tekrar aramaktan kaçınmak için yeterince akıllıca düşünmüyorum , bu nedenle hıza ihtiyacınız varsa, -prunebunun gibi kullanın :

 find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*some text*' -print

-printSonunda ihtiyacınız olan sonuncuyu not edin ! Ayrıca, emin olun -name '\.*' would be more efficient instead of -path` (yol alt yollar arıyor, ancak bunlar
budanacak

.Bu bağlamda özel anlamı nedir ?
frostschutz

@frostschutz Sonrasında nokta find, geçerli dizin anlamına gelir: geçerli finddizin altındaki tüm dosyalara ve dizinlere bakar. Bundan sonraki argüman path, bir noktanın normalde "herhangi bir karakter" anlamına geldiği normal bir ifadedir, bunun anlamsal bir nokta olması için ters eğik çizgi ile kaçmamız gerekir. Argüman normal bir ifade -name değildir , ancak bir kabuk gibi ?ve *benzeri joker karakterleri genişletir .
Ocak'ta 15:15

2
@frostschutz Aslında, bir düşünün, .özel bir anlama sahip olmak konusunda yanılmış olabilirim .
Flimm

1
@ Flimm yup, kaçmaya gerek yok .. Bildiğim kadarıyla farkındayım gibi sadece bu kaçan gerekir: *, ?, ve [].
thdoan

10

Bu, BSD, Mac ve Linux'ta da doğru çalışan nokta dosyalarının dışlanmasının birkaç yolundan biridir:

find "$PWD" -name ".*" -prune -o -print
  • $PWD tam yolu geçerli dizine yazdır, böylece yol başlamaz ./
  • -name ".*" -prune nokta ile başlayan ve sonra inmeyen dosya veya dizinlerle eşleşir
  • -o -printönceki ifade hiçbir şey ile eşleşmezse, dosya adını yazdırmak anlamına gelir. Kullanmak -printveya -print0diğer tüm ifadelerin varsayılan olarak yazdırılmamasına neden olur.

Lütfen "endişe verici şekilde karmaşık" ifadelerini açıklayın / ayrıntılandırın; Zaten verilen cevaplar ve cevabın aksini kanıtlamak gibi görünüyor ...?
natty

2
"endişe verici derecede karmaşık" muhtemelen çok fazla. Bu noktaya gelebilmek için cevabı cevapladım. Gönderdiğim cevabın anlaşılmasının zor olduğunu ve man sayfasını çok dikkatli bir şekilde okumadan görmenin zor olduğunu düşünüyorum. Eğer sadece GNU'yu buluyorsanız, o zaman daha olası çözümler var.
eradman

-o ... -printyardımcı olur. Benim kullanımım için, şimdi find ... '!' -name . -name '.*' -prune -o ... -print$ PWD'yi kullanmaktan daha uygun bir yöntemim var.
Roger Pate,

4
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)

Tüm gizli dizinleri ve $ DIR altındaki gizli dosyaları içermez


Bu mükemmel bir cevap. Tüm dosyaları yinelemeli olarak bulur, ancak dizinler ve gizli dosyalar için satır öğelerini hariç tutar. Teşekkürler!
KyleFarris

2

Cevap Başlangıçta yukarıda benim orijinal sorusuna "düzenlemek" olarak yayınlanmıştır:

find . \( ! -regex '.*/\..*' \) -type f -name "whatever", Eserleri. Regex "bir şey, sonra bir eğik çizgi, sonra bir nokta, sonra bir şey" (yani alt klasörleri de dahil olmak üzere tüm gizli dosya ve klasörler) ve "!" regex'i olumsuzlar.


Benzer, ancak yalnızca geçerli klasör için:find . \( ! -regex './\..*' \) -type f -maxdepth 1 -print
phyatt

2

Bunun için kullanmak zorunda değilsin find. Sadece globstar'ı kendin gibi kullan.

echo **/*foo*

veya:

ls **/*foo*

nerede **/yinelemeli herhangi bir klasör ve temsil *foo*sahip herhangi bir dosya fooadında.

Varsayılan olarak kullanmak ls, gizli dosyalar ve dizinler hariç dosya adlarını yazdıracaktır.

Globbing özelliğini etkinleştirmediyseniz, bunu yapın shopt -s globstar.

Not: Yeni bir globbing seçeneği Bash 4, zsh ve benzeri mermilerde işe yarar.


Örnek:

$ mkdir -vp a/b/c/d
mkdir: created directory 'a'
mkdir: created directory 'a/b'
mkdir: created directory 'a/b/c'
mkdir: created directory 'a/b/c/d'
$ touch a/b/c/d/foo a/b/c/d/bar  a/b/c/d/.foo_hidden a/b/c/d/foo_not_hidden
$ echo **/*foo*
a/b/c/d/foo  a/b/c/d/foo_not_hidden

5
Buna ihtiyacın yok ls! echo **/*foo*
Kevin Cox

@ kenorb (ve @ kevin-cox). Biraz daha ayrıntılı olabilir misiniz? Globstar (= *) neden burada çalışıyor ve nasıl? Eğik çizgi ne yapar / ne yapar?
natty

@ nuttyaboutnatty /, klasör anlamına gelir, dizinleri dosya adından ayırır. *temelde her şeyi temsil eder.
kenorb

@ kenorb evet-ama: bu tek gömlek asıl soruya nasıl yardımcı oluyor?
Natty

1
@ nuttyaboutnatty Netleştirildi ve örnek eklendi. Gizli olanı görmezden gelen dosyaları bularak yardımcı olur.
kenorb

1

@ Flimm'ın cevabı iyidir, çünkü bulmanın gizli dizinlere inmesini engeller . Bu sadeleştirmeyi tercih ediyorum:

Genellikle tüm gizli yolları dışlamak (normal dosyalar, dizinler vb.):

find <start-point> -path '*/.*' -prune -o <expression> -print

Örneğin, çalışma dizininizi başlangıç ​​noktası ve -name '*some text*'ifade olarak kullanmak:

find . -path '*/.*' -prune -o -name '*some text*' -print

@ Flimm'ın cevabının önerdiğinin aksine, hiçbir gizli dosya veya gizli dizin basit bir durum değildir. -path '*/.*'İfadesi olan herhangi yolunun (düzenli dosyalar, dizinler, vs) için de geçerlidir ., derhal dosya ayırıcı sonra /. Bu yüzden bu satır hem gizli dosyalara hem de klasörlere budanacak.

Gizli dizinleri hariç tutarken gizli dosyalara izin vermek, daha fazla filtre gerektiren durumdur. Bu, -type dbudanmakta olan ifadeye dahil edeceğiniz yerdir .

find <start-point> -type d -path '*/.*' -prune -o <expression> -print 

Örneğin:

find . -type d -path '*/.*' -prune -o -name '*some text*' -print

Bu durumda -type d -path '*/.*', trueyalnızca dizinler içindir ve bu nedenle yalnızca dizinler budanır.


0

findGibi düzgün mantık anahtarları vardır -andve -notbunları iki kural ile eşleşen bir dosyayı bulmak için kendi yararınıza kullanabilirsiniz:

$ touch non_hidden_file.txt .hidden_file.txt somethings/.another_hidden_file.txt                                                 

$ find . -type f -name '*hidden_file*' -and \( -not -name ".*" \)                            
./non_hidden_file.txt

Gördüğünüz gibi, findiki kural kullanır -name '*hidden_file*'ve -and \( -not -name ".*" \)her iki koşulla eşleşen dosya adlarını bulmak için kullanır - içindeki dosya adı hidden_fileancak başında nokta olmadan. Parantezin önündeki eğik çizgileri not edin - parantezi findbir alt kabuk tanımlamak yerine argüman olarak tanımlamak için kullanılırlar (bu parantezin aksi halde eğik çizgiler olmadan ne anlama geldiğidir)


0
$ pwd
/home/victoria

$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort
/home/victoria/new
/home/victoria/new1
/home/victoria/new2
/home/victoria/new3
/home/victoria/new3.md
/home/victoria/new.md
/home/victoria/package.json
/home/victoria/Untitled Document 1
/home/victoria/Untitled Document 2

$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2

Notlar:

  • . : geçerli klasör
  • -maxdepth 1yinelemeli olarak aramak için kaldır
  • -type f: (Dosyaları değil dizinleri bulmak d)
  • -not -path '*/\.*' : geri dönme .hidden_files
  • sed 's/^\.\///g': ./sonuç listesinden hazırlananları kaldır
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.