Taruhan terbaik saya saat ini adalah:
for i in $(find . -name *.jpg); do echo $i; done
Masalah: tidak menangani spasi dalam nama file.
Catatan: Saya juga suka cara grafis untuk melakukan ini, seperti perintah "tree".
Taruhan terbaik saya saat ini adalah:
for i in $(find . -name *.jpg); do echo $i; done
Masalah: tidak menangani spasi dalam nama file.
Catatan: Saya juga suka cara grafis untuk melakukan ini, seperti perintah "tree".
Jawaban:
Cara kanonik adalah melakukan
find . -name '*.jpg' -exec echo {} \;
(ganti \;dengan +untuk meneruskan lebih dari satu file echosekaligus)
atau (spesifik GNU, meskipun beberapa BSD sekarang juga memilikinya):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echoyang memperluas urutan melarikan diri seperti \b(setidaknya konforman Unix echo).
findmanual ditampilkan find . -type f -exec file '{}' \;di EXAMPLESbagian. Mungkin beberapa kerang akan memperlakukan kawat gigi secara khusus.
'{}', \{\}, {}, "{}", '{'}diperluas oleh shell (apapun Bourne-seperti shell) untuk satu argumen untuk menemukan bahwa adalah dua karakter "{" dan "}". Ganti "menemukan" dengan "echo menemukan", atau printf '<%s>\n' findjika Anda ingin melipatgandakan-cek.
Jawaban yang lebih baik telah diberikan.
Tetapi perhatikan bahwa spasi bukan satu-satunya masalah dalam kode yang Anda berikan. tab, baris baru dan karakter wildcard juga merupakan masalah.
Dengan
IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done
Maka hanya karakter baris baru yang menjadi masalah.
Apa yang Anda sebutkan adalah salah satu masalah dasar yang dihadapi orang, ketika mereka mencoba membaca nama file. Terkadang, orang-orang dengan pengetahuan terbatas dan memiliki kesalahpahaman tentang struktur file dan folder cenderung lupa bahwa " Dalam UNIX Semuanya adalah file ". Jadi mereka tidak mengerti bahwa mereka perlu menangani spasi juga, karena nama file dapat terdiri dari 2 kata atau lebih dengan spasi.
Solusi: Jadi salah satu cara yang lebih dikenal untuk melakukan ini adalah dengan melakukan pembacaan yang bersih .
Kita di sini akan membaca semua file yang ada dan menyimpannya dalam sebuah variabel, lain kali ketika melakukan pemrosesan yang diinginkan kita hanya perlu menyimpan variabel itu di dalam tanda kutip yang akan menjaga nama file dengan spasi. Ini adalah salah satu cara dasar untuk melakukannya, namun, jawaban lain yang diberikan oleh orang lain di sini juga berfungsi.
SCRIPT:
find /path/to/files/ -iname "*jpg" | \
while read I; do
cp -v --parent "$I" /backup/dir/
done
Di sini saya membaca file dengan memberikan path kepada mereka dan apa pun yang saya baca saya menyimpannya di dalam variabel I, yang akan saya kutip di kemudian hari saat memprosesnya untuk melestarikan ruang sehingga memprosesnya dengan benar.
Semoga ini bisa membantu Anda dalam beberapa cara.
Cukup dengan finddan bash:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
Dengan cara ini, kami menggunakan $1dalam bash, seperti dalam naskah dasar, yang membuka perspektif yang bagus untuk melakukan tugas-tugas lanjutan (atau tidak).
Cara yang lebih efisien (untuk menghindari keharusan memulai bash baru untuk setiap file):
find . -name '*.jpg' -exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done' -- {} +
Di versi bash terbaru, Anda dapat menggunakan globstaropsi:
shopt -s globstar
for file in **/*.jpg ; do
echo "$file"
done
Untuk tindakan sederhana, Anda bahkan dapat melewatkan loop sepenuhnya:
echo **/*.jpg
set -G), itu tidak boleh digunakan dalam bash karena versi bash rusak secara mendasar (seperti GNU grep -r) karena turun ke symlink ke direktori (setara dengan find -Latau zsh's ***/*.jpg). Juga perhatikan bahwa bertentangan dengan menemukan, itu akan menghapus dotfiles dan tidak turun ke dotdirs (secara default).
$i? Saya melakukan itu dan itu berfungsi dengan baik. Apakah ada yang salah dengan pendekatan itu?