Belirtilen uzantıları olmayanlar dışındaki bir dizindeki her dosyayı nasıl listeleyebilirim?


28

Diyelim ki .txt , .pdf ve diğer dosyaları içeren bir klasörüm var . "Diğer" dosyaları (yani .txt veya .pdf uzantılı dosyaları) listelemek istiyorum . Bunun nasıl yapılacağı hakkında herhangi bir tavsiyeniz var mı?

Belirli bir uzantıya sahip olmayan dosyaları nasıl listeleyeceğimi biliyorum. Örneğin, .txt dosyaları dışındaki tüm dosyaları listelemek istersem ,

find -not -iname "*.txt"

veya

ls | grep -v '\.txt$' | column

iş gibi görünüyor. Ancak, .txt dosyaları veya .pdf dosyaları dışındaki her şeyi nasıl listeleyebilirim ? Görünen o ki, mantıklı bir şekilde "veya" findya da içinde bir mantık kullanmam gerekiyor grep.


2
lsVs findvs globbing davranışının gizli nokta dosyalarında farklı olabileceğini unutmayın.
jw013

1
Akılda tutulması gereken bir şey daha: findözyinelemeli gibi, alt dizinleri geçecek ls. Daha fazla davranmasını sağlamak için -maxdepth 1ile kullanın . findls
jw013

Yani özyinelemeli değil, sadece geçerli dizindeki dosyaları listele?
papatya

Yanıtlar:


28

Birinin uygun bir sürümünün olduğunu varsayarsak ls, bu muhtemelen en basit yoldur:

ls -I "*.txt" -I "*.pdf"

Tüm alt dizinlerde yineleme yapmak istiyorsanız:

ls -I "*.txt" -I "*.pdf" -R

8
GNU lsseçenekleri taşınabilir değildir.
bahamat

4
lsZaten taşınabilir komut dosyalarına gerçekten ait değil, bu nedenle OP'nin yalnızca etkileşimli kullanım hakkında sorduğu varsayılıyor.
jw013

1
Neden taşınabilir değil? O zaman ne kullanmalıyım?
Freedo,

28

Destek bul -o

find . ! '(' -name '*.txt' -o -name '*.pdf' ')'

Önceliği doğru yapmak için parantez gerekir. Bul çok şey yapar; Ben onun sayfasını okumanızı öneririm.

Ayrıca bir veya içinde de yapabilirsiniz grep(ancak gerçekten çıktısını ayrıştırmamalısınızls )

ls | grep -Ev '\.(txt|pdf)$' | column

1
Teşekkürler! Neden çıktısını ayrıştırmamalıyım ls?
Andrew

6
@Andrew, çünkü kırılgan (içinde yeni bir satır bulunan bir dosya adı düşünün - evet, geçerli bir dosya adı - find'in -print0 / -exec / -delete / etc. Bu problemi önleyin); ikincisi, çünkü genellikle daha kolay bir yol var.
derobert

Ek olarak findman sayfasına, bütün kalbiyle ilgili Unix Elektrikli El Aletleri makaleleri tavsiye findgibi, docstore.mik.ua/orelly/unix3/upt/ch09_06.htm ve docstore.mik.ua/orelly/unix3/upt/ch09_12.htm
Joker karakter

Sadece insanlar için olan ifadenin find . NOT ( *.txt OR *.pdf )
kodunun

12

İle bash (ile açmak globbing genişletilmiş shopt -s extglob), glob !(*.txt|*.pdf)çalışmalıdır. Bu küreyi doğrudan dahil ancak bunlarla sınırlı olmamak üzere dosya argümanlarını alan herhangi bir komuta geçirebilirsiniz ls.


1
+1 ancak alt dizinleriniz varsa içerikleri de listelenir; Bundan -dkaçınmak için kullanın :ls -d !(*.txt|*.pdf)
legends2k 11:14

Teşekkür ederim, tam olarak birden fazla dosyayı kabul etmek için bir sözdizimi arıyordum, bu tam olarak burada uygun olacak stackoverflow.com/questions/216995/…
Freedo

6

İçinde zsh ile extendedglob:

print -rl -- *~*.(txt|pdf)

veya

print -rl -- ^*.(txt|pdf)

Veya ile kshglob (evet, "bash genişletilmiş globbing" değil, ksh globbing):

print -rl -- !(*.txt|*.pdf)

Bunların nokta dosyaları da içermediğini unutmayın.

ksh93 FIGNORE(mis) özelliğine sahiptir:

FIGNORE='@(.|..|*.txt|*.pdf)'
printf '%s\n' *


3

Derobert tarafından önerildiği gibi, en iyi bahis kullanmaktır find. Ancak, olabilir aslında diğer komutlarla bir boru hattı sonucu kullanın.

GNU (ve bazı BSD'ler) , NUL karakteriyle sonlandırılan dosya adını yazdırmasını söyleyen , hangi karakterin bir dosya adında izin verilmediğini ve bir çarpışmanın olmayacağının garantisi findolan -print0yüklemeyi destekler . Diğer komutları kullanmanız istenebilir.NUL'u giriş sınırlayıcısı olarak .

Bunlardan en önemlisi GNU xargs, sizin belirlediğiniz komutu çalıştırır ve dosya listesine komut satırı argümanları olarak iletir. xargs -r0Find's -print0örneği ile birlikte çalıştırmak istersiniz.

find . -type f ! \( -name \*.pdf -o -name \*.txt \) -print0 | xargs -r0 ls -ld

Bu güvenle tüm pdf ve uzun bir dizin listesini yazdırır , adında boşluk veya yazdırılamayan karakterler içeren txt dosyalarının .

GNU tarile aşağıdaki gibi de kullanabilirsiniz :

tar -zcf myarchive.tar.gz --null --files-from <(
  find . -type f ! -name \*.tar.gz -print0)

Bu, adları .tar.gz ile bitmeyen tüm dosyaların tar.gz dosyasını oluşturur.

rsyncayrıca -0, diğerleriyle olduğu gibi , parametreyle boş ayrılmış dosyaları da kabul eder . Ancak xargs, genellikle bu tür bir amaç için kullanacağınız yapıştırıcıdır. O ya Ya find'ın -execözelliği.


tarKomut örneği iyi biridir. Yine de çoğu amaç -execiçin daha uygun.
Wildcard

1

Bir alt dizininiz yoksa

ls !(*.pdf|*.txt)

Ayrıca çalışması gerekir!

Fakat

ls -I "*.pdf" -I "*.txt"

ortak yoldur.


0

Tamamlayıcı olarak, bash uyumlu bir kabuk kullanıyorsanız, özgeçmişleri desen eşlemesinden çıkarmak için GLOBIGNORE değişkenini kullanabilirsiniz. Adamdan:

   GLOBIGNORE
          A colon-separated list of patterns defining the set of filenames
          to be ignored by pathname expansion.  If a filename matched by a
          pathname  expansion  pattern also matches one of the patterns in
          GLOBIGNORE, it is removed from the list of matches.

Özel bir durumda:

sh$ (GLOBIGNORE='*.pdf:*.txt'; ls -d *)

Lütfen etkileşimli kabuğumun GLOBIGNORE ortam değişkenini değiştirmemek için bu komutu alt kabuk (parantez kullanarak) olarak çalıştırdığımı unutmayın.

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.