Dizinler olmadan dosyaları listeleme ve ada göre filtreleme (ls seçenekleri)


42

Bende bir dizin var uploads. Bir sürü dosya ve bunun yanında sırayla dosyaları içeren birkaç alt dizini içerir.

Yapabileceğim bir yol var mı (bir adımda) aşağıdakileri yapın:

  1. SADECE kök dizinindeki dosyaları listele dizin - Alt klasör adlarını veya içeriğini görmek istemiyorum;

    ve

  2. İle başlayan dosyaları listelemeyin t_

-dBayrak hakkında bilgim var , ama istediğimden tam olarak emin değil.

Yanıtlar:


53

Bunun için bir iş gibi geliyor find.

  • -maxdepthYalnızca geçerli dizini döndürmek için kullanın , alt klasörlerde tekrar tekrar arama yapmayın
  • -type fYalnızca dosyaları, dizinleri veya cihaz düğümlerini veya başka bir şeyi geri döndürmemek için kullanın
  • İstemediğiniz isimleri olan dosyalardan kaçınmak için eğer -notve bir kombinasyonu kullanın.-name

Böyle bir araya gelebilir:

find /path/to/uploads -maxdepth 1 -type f -not -name 't_*'

Teşekkürler! CLI için oldukça yeniyim ve daha önce hiç bulmadım. Kesinlikle daha yakından bakacağım.
EmmyS

2
@EmmyS: Burada bir tane daha küçük numara bulabilirsin. @ Gilles -exec ls -lG -- {} +, çıktısını almak için ls’e ekstra seçenekler kullanarak cevapında bahsetti . -lsLs'ın detaylı görüşüne hızlı ve kirli bir şekilde yaklaşmak için bu bulguyu da ekleyebilirsiniz .
Caleb

18

GNU ls (yani gömülü olmayan Linux sistemlerindeki ls komutu ve diğer bazı birliklerde de bulunan Cygwin) isimlerini baz alarak bazı dosyaları gizleme seçeneğine sahiptir. Ancak dizinleri görmezden gelmenin bir yolu yok.

ls --hide='t_*' uploads

Başka bir yaklaşım kabuğunuzu eşleştirmeyi sağlamaktır. Bash, ksh ve zsh, eşleşenler !(t_*)dışındaki tüm dosyaları eşleştirmek için bir olumsuzlama düzenine sahiptir t*; bash'da bu özelliğin açık olması shopt -s extglobve zsh'de de açık olması gerekiyor setopt ksh_glob. Zsh ^t_*, açılması gereken eşdeğer bir sözdizimine de sahiptir setopt extended_glob. Bu hala dizinleri görmezden gelmiyor. Zsh, dosyaları yalnızca ada göre değil aynı zamanda meta veriler ve daha fazlasıyla da eşleştirmenize izin veren ek bir özelliğe sahiptir: glob niteleyicileri . (.)Düzenli dosyaları kısıtlamak için eşleşmenin sonuna ekleyin . Olumsuzluk ^, ad eşleştirme sözdiziminin bir parçasıdır, bu ^t_*(.)nedenle “normal dosyalar eşleşmeyen t_*tüm dosyalar” değil “ eşleşmeyen tüm normal dosyalar” anlamına gelir t_*.

setopt extended_glob  # put this in your ~/.zshrc
ls uploads/^t_*(.)

Kendinizi gelişmiş araçlar olmadan bulursanız, bunu herhangi bir unix ile yapabilirsiniz find. Genelde komut satırına yazacağın türden bir şey değil, ama güçlü ve kesin. Caleb, GNU bulgusu ile bunun nasıl yapıldığını çoktan gösterdi . Bu -maxdepthseçenek taşınabilir değildir; Özyinelemeyi -pruneengellemek için, bunun yerine kullanabilirsiniz find.

find uploads/* -type d -prune -o \! -type f -name 't_*' -print

Değiştir -printtarafından -exec ls -lG -- {} +yürütülecek lsdosyalar üzerinde favori seçenekleri ile.

Yukarıdaki tüm komutlar nokta dosyalarını gizler (yani adı a ile başlayan dosyalar .). Eğer onları görüntülemek geçmek istiyorsanız -Aiçin ls, ya da eklemek Dzsh glob eleme ( ls uploads/^t_*(.D)). Bununla find, yalnızca bir seviye yineleme yapmak için farklı bir yaklaşım kullanabilirsiniz ( findnokta dosyalarını özel olarak işlemez). Bu, yalnızca findgeçerli dizinde çalıştırıyorsanız tam olarak çalışır .

cd uploads && find . -name . -o -type d -prune -o \! -type f -name 't_*' -print

3
Bir günlük işin var mı? ;-) Unix SE! 'Deki en basit görünen sorulara rağmen cevaplarınızın detayı ve uzunluğu konusunda sürekli hayran kaldım! .. Yine de devam et! :)
alex

Teşekkürler! Güzel detay. Şu an "gelişmiş araçlara" sahip olup olmadığımı bilmiyorum; Mac'te
işteyim

@EmmyS: Linux kutunuz için benim kullanımım -maxdepthişe yaramalı , ancak Gilles 'in bahsettiği “taşınabilirlik” problemi BSD'nin find(sanırım OSX’te de buldum) biraz farklı bir hayvan olduğudur, bu yüzden onun cevabına da ihtiyacın olabilir. @Gilles: zsh numarası için +1!
Caleb

1
@Gilles: Bazıları hakkında çok sulu olmayan yorumlar pruneaklıma geldi, ama şunu söyleyerek bırakacağım diyerek, kendi sistemime girdiğimde, " bu komutun açık olsaydı, bu komutun işe yarayacağını " söyleyeceğim. AIX, Solaris veya MINIX3 "yaklaşık ... beklemede ... Sayaç okuması zor oluyor ... ekran donuyor 0.00.
Caleb

2
Gnu'nun lsbir --use-telepathyseçeneği yok mu? İstediğiniz dosyaları görüntülemenin en hızlı yolu budur. Yine de taşınabilir olmayabilir.
dubiousjim

8
ls -l /folder | grep ^- | awk '{print $9}'

$9Bu açıklamanın içinde ne var ?
EmmyS

3
@EmmyS Çıktının 9. alanı / sütunu anlamına gelir. Bu cevap çıktıyı ayrıştırmayals çalışıyor .
jw013

print $ NF` daha iyi olurdu, IMO. $ NF, 9 olan ve diğerlerine $ NF'yi öğretmek için iyi bir fırsat olarak AWK'da yaygın bir kullanım olan alan sayısını ifade eder.
Elijah Lynn,

1
ls -l | grep -v ^d | grep name$

Bu çözümü neye tercih eder (çoklu komut ve borular gerektirir) find?
HalosGhost,

Özlü, okunması kolay ve ls emir sözleşmesiyle birlikte kalır. Hatırla komutunun argümanlarından daha kolay hatırlıyorum. Her biri için kendi ve seçenekleri için şeref!
tkjef

0

Bir atış yapıp lsborular kullanmama izin ver :

ls  -l --hide='t_*'  uploads/ | grep -v ^d | tr -s ' ' | cut -d ' ' -f 9

Son sütunda 9. olanı söyle.


1
Ya boşluk içeren dosyalar varsa?
jordanm

0

Find's -maxdepth taşınabilirlik sorunu bir endişe ise, kullanabilirsiniz:

ls -l uploads/ | awk '/^-/ && $9 !~/^t_/ {print $9}'

Uzman değilim ama bunun işe yarayacağını düşünüyorum. Sanırım biraz şifreli görünüyor, ama awk konuşursanız, gerçekten değil. 9 $ yerine $ NF kullanılabilir. Ayrıca şunları da yapabilirsiniz:

ls -l uploads/ | awk '/^-/' | awk '!/^t_/ {print $9}'

aynı şeyi yapar (ama öncekinden daha az verimli olabilir).

Aslında, diğer yazılar hakkında düşündükten sonra,

ls -l --hide=t_* uploads/ | awk '/^-/ {print $9}'

daha da kısa ve net bir yoldur.

Birisi lütfen yanılıyorsam beni düzelt. :-)


Ayrıştırma lsgenellikle iyi bir fikir değildir . Sizin awk hileler, örneğin içinde boşluk olan dosya adları ile başarısız olur.
Mat

@ mat - Düzeltme için teşekkürler. Sizin (ve jw013) olduğuna dikkat çeken makaleyi okuduktan sonra, görüyorum ls çıktı doğru dosya adlarına güvenilemez. Ben 9 $ dan satırın sonuna kadar her şeyi yazdırmak için awk kodunu yeniden yazmak olsa bile (boşlukları dahil etmek), bu ls çıktı hala hatalı olabilir. Bu hayal kırıklığı yaratıyor ve düzeltilmeli IMO. Tekrar teşekkürler.
kkaszub

0

Bu kısa yolları buldum:

ls -p uploads | grep -Ev '/'

veya

ls -pIt_* uploads | grep -v /

-1

Bu takma adı deneyin ve kullanın:

alias l='ls -hLlF'

ls -hLlFalt dizinleri gösterir ve ile başlayan dosyaları gösterir t_. Peki bu soruya nasıl cevap veriyor?
Raphael Ahrens

Belki de soruyu yanlış anladım. ls -hLlF, bağlantılı dizinlerin hedef dizinlerini göstermez.
Granüler

Öyle görünüyor. Fakat sorunun diğer cevaplarını okumadın mı?
Raphael Ahrens

-1

Tereyağından kıl çeker gibi:

ls -l --hide 't_*' <absolute path to desired directory> | grep -v ^d


(1) Bu cevap çok kolay, daha önce verildi. (2) Neden dizinin tam yolunu belirtmeniz gerektiğine inanıyorsunuz?
Scott,

@Scott - bu, çözüme ulaşmak için çok hızlı ve basit bir yoldur. Tam yolu cevabı evrensel hale getirmek için belirlendi ...
Digger 5
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.