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 echo
sekaligus)
atau (spesifik GNU, meskipun beberapa BSD sekarang juga memilikinya):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echo
yang memperluas urutan melarikan diri seperti \b
(setidaknya konforman Unix echo
).
find
manual ditampilkan find . -type f -exec file '{}' \;
di EXAMPLES
bagian. 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' find
jika 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 find
dan bash
:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
Dengan cara ini, kami menggunakan $1
dalam 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 globstar
opsi:
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 -L
atau 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?