Saya perlu mengulang direktori secara rekursif dan menghapus semua file dengan ekstensi .pdf
dan .doc
. Saya mengelola untuk mengulang direktori secara rekursif tetapi tidak berhasil memfilter file dengan ekstensi file yang disebutkan di atas.
Kode saya sejauh ini
#/bin/sh
SEARCH_FOLDER="/tmp/*"
for f in $SEARCH_FOLDER
do
if [ -d "$f" ]
then
for ff in $f/*
do
echo "Processing $ff"
done
else
echo "Processing file $f"
fi
done
Saya perlu bantuan untuk menyelesaikan kode, karena saya tidak mendapatkan apa-apa.
rm
adalah bagian dari kode OP, tetapi sebenarnya tidak relevan dengan pertanyaan yang diajukan. Saya pikir akan lebih aman jika jawaban diungkapkan menggunakan perintah yang tidak berbahayaecho
.Jawaban:
find
hanya dibuat untuk itu.sumber
-delete
opsi temukan .find ... -print0 | xargs -0 ...
, bukan mencari mentah | xargs untuk menghindari masalah dengan nama file yang mengandung baris baru.xargs
tanpa opsi hampir selalu merupakan saran yang buruk dan ini tidak terkecuali. Gunakanfind … -exec
sebagai gantinya.Sebagai tindak lanjut dari jawaban mouviciel, Anda juga bisa melakukan ini sebagai for for, alih-alih menggunakan xargs. Saya sering menemukan xargs rumit, terutama jika saya perlu melakukan sesuatu yang lebih rumit di setiap iterasi.
Seperti yang dikomentari sejumlah orang, ini akan gagal jika ada spasi dalam nama file. Anda dapat mengatasi ini dengan mengatur sementara IFS (internal field seperator) ke karakter baris baru. Ini juga gagal jika ada karakter wildcard
\[?*
dalam nama file. Anda dapat mengatasinya dengan menonaktifkan sementara ekspansi wildcard (globbing).Jika Anda memiliki baris baru dalam nama file Anda, maka itu tidak akan berhasil. Anda lebih baik dengan solusi berbasis xargs:
(Kurung yang lolos diperlukan di sini untuk memiliki
-print0
berlaku untuk keduaor
klausa.)GNU dan * BSD find juga memiliki
-delete
aksi, yang akan terlihat seperti ini:sumber
for f in $(find ...)
. Hanya saja, jangan gunakan metode ini.Tanpa
find
:/tmp/*
adalah file dalam dir dan/tmp/**/*
file dalam subfolder. Mungkin saja Anda harus mengaktifkan opsi globstar (shopt -s globstar
). Jadi untuk pertanyaan kodenya akan terlihat seperti ini:Perhatikan bahwa ini membutuhkan bash ≥4.0 (atau zsh tanpa
shopt -s globstar
, atau ksh denganset -o globstar
bukanshopt -s globstar
). Selanjutnya, dalam bash <4.3, ini melintasi tautan simbolik ke direktori serta direktori, yang biasanya tidak diinginkan.sumber
for f in /tmp/**
akan cukup. Termasuk file dari / tmp dir.for f in /tmp/*.{pdf,doc} tmp/**/*.{,pdf,doc} ; do
**
adalah ekstensi yang bagus tetapi tidak portabel untuk POSIXsh
. (Pertanyaan ini ditandai dengan bash tetapi akan lebih baik untuk menunjukkan bahwa tidak seperti beberapa solusi di sini, ini benar-benar hanya untuk Bash. Atau, well, ia juga berfungsi di beberapa shell yang diperluas.)Jika Anda ingin melakukan sesuatu secara rekursif, saya sarankan Anda menggunakan rekursi (ya, Anda bisa melakukannya menggunakan tumpukan dan sebagainya, tapi hei).
Yang mengatakan,
find
mungkin merupakan pilihan yang lebih baik seperti yang telah disarankan.sumber
Berikut ini contoh menggunakan shell (
bash
):sumber
Ini tidak menjawab pertanyaan Anda secara langsung, tetapi Anda dapat menyelesaikan masalah Anda dengan satu kalimat:
Beberapa versi find (GNU, BSD) memiliki
-delete
tindakan yang dapat Anda gunakan alih-alih memanggilrm
:sumber
Metode ini menangani ruang dengan baik.
Edit, perbaiki satu per satu
sumber
Untuk bash (sejak versi 4.0):
Itu saja.
Ekstensi tambahan ".ext" di sana untuk memilih file (atau dir) dengan ekstensi itu.
Opsi globstar mengaktifkan ** (pencarian secara berulang).
Opsi nullglob menghapus * ketika tidak cocok dengan file / dir.
Opsi dotglob termasuk file yang mulai dengan titik (file tersembunyi).
Berhati-hatilah bahwa sebelum bash 4.3,
**/
juga melintasi tautan simbolik ke direktori yang tidak diinginkan.sumber
Fungsi berikut akan secara berulang mengulangi semua direktori dalam
\home\ubuntu
direktori (seluruh struktur direktori di bawah Ubuntu) dan menerapkan pemeriksaan yang diperlukan dalamelse
blok.sumber
Ini adalah cara paling sederhana yang saya tahu untuk melakukan ini:
rm **/@(*.doc|*.pdf)
**
membuat ini bekerja secara rekursif@(*.doc|*.pdf)
mencari file yang berakhiran pdf OR docMudah diuji dengan aman dengan menggantinya
rm
denganls
sumber
Tidak ada alasan untuk menyalurkan output
find
ke utilitas lain.find
memiliki-delete
bendera yang terpasang di dalamnya.sumber
Jawaban lain yang diberikan tidak akan menyertakan file atau direktori yang dimulai dengan a. berikut ini bekerja untuk saya:
sumber
Kerjakan saja
sumber
Berikut ini akan berulang melalui direktori yang diberikan secara rekursif dan daftar semua konten:
for d in /home/ubuntu/*; do echo "listing contents of dir: $d"; ls -l $d/; done
sumber
ls -l /home/ubuntu/*/
, jadi sangat tidak berguna.Jika Anda dapat mengubah shell yang digunakan untuk menjalankan perintah, Anda dapat menggunakan ZSH untuk melakukan pekerjaan itu.
Ini akan berulang secara berulang melalui semua file / folder.
sumber