Şu anki en iyi bahisim:
for i in $(find . -name *.jpg); do echo $i; done
Sorun: Dosya adlarındaki boşlukları işlemiyor.
Not: Bunu "ağaç" komutu gibi grafiksel bir şekilde yapmak isterdim.
Şu anki en iyi bahisim:
for i in $(find . -name *.jpg); do echo $i; done
Sorun: Dosya adlarındaki boşlukları işlemiyor.
Not: Bunu "ağaç" komutu gibi grafiksel bir şekilde yapmak isterdim.
Yanıtlar:
Kanonik yol yapmak
find . -name '*.jpg' -exec echo {} \;
( bir kerede birden fazla dosya aktarmak için \;
ile değiştirin )+
echo
veya (GNU'ya özgü, ancak bazı BSD'lerde de var):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echo
Gibi kaçış dizilerini \b
(en azından Unix uyumluları echo
) genişleten bir gelişme kullanılmayacaktır .
find
Manpage gösterir find . -type f -exec file '{}' \;
içinde EXAMPLES
bölümü. Belki bazı mermiler diş tellerini özel olarak tedavi eder.
'{}'
, \{\}
, {}
, "{}"
, '{'}
"{" ve "}" iki karakterdir bulmak için bir argüman için kabuk (her ne Bourne benzeri kabuk) tarafından genişletilir. "Find" ifadesini "echo find" ile değiştirin veya printf '<%s>\n' find
tekrar kontrol etmek istiyorsanız.
Daha iyi yanıtlar verilmiş.
Ancak, kodda verilen boşlukların boşluk olmadığını unutmayın. sekme, satırsonu ve joker karakterler de bir sorundur.
İle
IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done
O zaman sadece yeni satır karakterleri sorun olur.
Bahsettiğiniz, dosya adlarını okumaya çalışırken insanların karşılaştığı temel sorunlardan biridir. Bazen, sınırlı bilgiye sahip olan ve dosya ve klasör yapısını yanlış anlayan insanlar " UNIX'te Herşey bir dosyadır " ını unutmaya eğilimlidir . Bu nedenle, dosya adı boşluklu 2 veya daha fazla kelimeden oluşabileceğinden boşlukları da işlemeleri gerektiğini anlamıyorlar.
Çözüm: Bunu yapmanın daha iyi bilinen yollarından biri temiz bir okuma yapmaktır .
Burada mevcut tüm dosyaları okuyacağız ve bir değişken içinde tutacağız, bir dahaki sefere istenen işlemi yaparken dosya değişkenlerini boşluklarla koruyacak tırnak işaretleri içinde tutmamız gerekecek. Bu, bunu yapmanın temel yollarından biridir, ancak burada diğer insanlar tarafından sağlanan diğer cevaplar da aynı şekilde çalışır.
SENARYO :
find /path/to/files/ -iname "*jpg" | \
while read I; do
cp -v --parent "$I" /backup/dir/
done
Burada onlara yol vererek dosyaları okuyorum ve ne okuyorsam ben onları daha sonra doğru şekilde işlemek için boşlukları korumak için işlerken daha sonraki bir noktada teklif edecek bir değişken I içinde saklıyorum.
Umarım bu size bir şekilde yardımcı olur.
Sadece find
ve ile bash
:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
Bu şekilde, $1
bash'de, temel bir komut dosyasında olduğu gibi, gelişmiş (veya değil) görevleri yerine getirmek için güzel perspektifler açıyoruz.
Daha etkili bir yol (her dosya için yeni bir bash başlatmak zorunda kalmamak için):
find . -name '*.jpg' -exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done' -- {} +
Bash'ın son sürümünde, globstar
seçeneği kullanabilirsiniz :
shopt -s globstar
for file in **/*.jpg ; do
echo "$file"
done
Basit işlemler için, döngüyü tamamen atlayabilirsiniz:
echo **/*.jpg
set -G
) ile çalışırken, bash sürümü, grep -r
dizinlere ( find -L
veya zsh'lara eşdeğer) bağlı olduğu için bash sürümü temelde kırıldığı için (tıpkı GNU gibi ) kullanılmamalıdır. ***/*.jpg
). Ayrıca, bulmanın aksine, nokta dosyalarını ommitleyeceğini ve dotdirs'e (varsayılan olarak) inmeyeceğini unutmayın.
$i
? Bunu yapıyorum ve iyi çalışıyor. Bu yaklaşımda bir sorun mu var?