Dizindeki dosyalar için, yalnızca yankı dosya adı (yol yok)


100

Bir dizini for döngüsü ile yinelersem, bir dosyanın yalnızca dosya adını yankılamaya nasıl başlayabilirim?

for filename in /home/user/*
do
  echo $filename
done;

dosya adı ile tam yolu çekecektir. Sadece dosya adını istiyorum.

Yanıtlar:


169

Yerel bir bashçözüm istiyorsanız

for file in /home/user/*; do
  echo "${file##*/}"
done

Yukarıdakiler , kabuğa özgü olan ve aşağıdaki gibi harici bir ikiliye çağrı gerektirmeyen Parametre Genişletmesini kullanır .basename

Ancak, sadece kullanmayı önerebilir miyim? find

find /home/user -type f -printf "%f\n"

10
İyi cevap. Parametre genişletme hakkında daha fazla bilgi edinmek isteyenler için: wiki.bash-hackers.org/syntax/pe#substring_removal
DougW

1
-printf: bilinmeyen birincil veya operatör => unix.stackexchange.com/a/272493/72893
Aurelio

2
Boşluklu dosya adlarını desteklemek ${file##*/}için değiştirmeyi düşünün "${file##*/}", örn. "Boşluk.txt ile dosya adım".
WinEunuuchs2Unix

1
echo "$ {file ## * /}" boş bir dize döndürür
Alessandro C

48

Sadece şunu kullanın basename:

echo `basename "$filename"`

$ Dosya adının boşluk içermesi durumunda tırnak işaretleri gereklidir.


3
parametre genişletmeyi kullanmak daha iyidir, harici ikili dosyalara çağrı gerektirmez.
SiegeX

5
Btw, `` kullanımdan kaldırıldı. $()Oli'nin yaptığı gibi kullanmak daha iyi
SiegeX

1
Bu eski yanıta yorum yaptığım için özür dilerim, ancak taban adı, boşluk içeren dosyalarda düzgün çalışmayacaktır. Örnek: PWD çıkışı: /test 1, basename $(pwd)çıkışı: test. OS X ve Ubuntu Sunucusunda (14.04) test edilmiştir. @SiegeX'in önerdiği gibi yerel bash çözümü benim için çalıştı.
Marko Grešak

@ MarkoGrešak basename "$(pwd)"Bunun yerine kullanın .
YoungFrog

@YoungFrog giriş için teşekkürler, ancak bu 9 ay önceydi. Ayrıca $PWDkomutu çalıştırmak yerine değişkeni kullanmak daha iyi olacaktır .
Marko Grešak

16

Kullanım basename:

echo $(basename /foo/bar/stuff)

Neden kullanıyorsun echo? basenamesonuçları zaten yazdırıyor. echoalt kabuğu alıntı yapmazsanız sonucu bile karıştırabilir. Örnek: echo $(basename path/with\ \ spaces)yanlış yazdırılıyor with spaces(yalnızca bir boşluk).
Socowi

8

Diğer bir yaklaşım, lsbir dizin içindeki dosya listesini okurken size istediğinizi, yani "sadece dosya adlarını" vermek için kullanmaktır. Tam dosya yolunu okumak ve ardından for döngüsünün gövdesindeki "dosya adı" bileşenini çıkarmaktan farklı olarak.

Orijinalinizi takip eden aşağıdaki örnek:

for filename in $(ls /home/user/)
do
  echo $filename
done;

Komut dosyasını dosyalarla aynı dizinde çalıştırıyorsanız, o zaman basitçe şöyle olur:

for filename in $(ls)
do
  echo $filename
done;

1
ls*genişlemenin genellikle bulunmadığı tüm nokta dosyalarını içerir . Ayrıca for f in $(...) ..., IFS'yi ayarlamadığınız sürece herhangi bir dosya adı boşluk içeriyorsa başarısız olur, -f / -o noglob ayarlamadığınız sürece herhangi bir dosya adı bir glob karakter içeriyorsa başarısız olabilir ve sistem veya kabuğa bağlı olarak, echoherhangi bir dosya adı tire + harf ise veya ters eğik çizgi içeriyorsa başarısız olabilir. OTOH, ls -1 /path/to/dirher bir dosya adını güvenilir bir şekilde bir satıra yazdırır, dotfiles farkını modüle eder.
dave_thompson_085

0

sadece dosya adı istiyorsanız:

for file in /home/user/*; do       
  f=$(echo "${file##*/}");
  filename=$(echo $f| cut  -d'.' -f 1); #file has extension, it return only filename
  echo $filename
done

cutkomut hakkında daha fazla bilgi için buraya bakı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.