menambahkan ekstensi file secara rekursif ke semua file

106

Saya memiliki beberapa direktori dan sub-direktori yang berisi file tanpa ekstensi file. Saya ingin menambahkan .jpgke semua file yang ada di dalam direktori ini. Saya telah melihat skrip bash untuk mengubah ekstensi file tetapi tidak untuk hanya menambahkan satu. Ini juga perlu rekursif, dapatkah seseorang membantu?

robjmills
sumber

Jawaban:

228

Perintah alternatif tanpa loop eksplisit ( man find):

find . -type f -exec mv '{}' '{}'.jpg \;

Penjelasan: ini secara rekursif menemukan semua file ( -type f) mulai dari direktori saat ini ( .) dan menerapkan perintah move ( mv) ke masing-masing file . Perhatikan juga tanda kutip di sekitarnya {}, sehingga nama file dengan spasi (dan bahkan baris baru ...) ditangani dengan benar.

Stephan202
sumber
7
Secara khusus, yang satu ini bekerja lebih baik jika ada banyak sekali file dalam struktur direktori (menyebabkan bash kesal tentang panjang daftar file yang diiterasi).
DrAl
@ Al, jika Anda merujuk ke forloop yang mengganggu bash untuk mengulang daftar file, itu tidak benar. forLoop bash secara berulang mengeluarkan setiap mvperintah.
nik
Pertanyaan: Apakah findpertama kali membuat daftar file sebelum menjalankan -execpernyataan? Saya rasa begitu, tetapi ingin memperjelas poin ini sebelum mengkodekan loop tak terbatas.
Boldewyn
2
perintah ini juga akan menemukan file dengan ekstensi. Itukah yang diinginkan OP?
ghostdog74
1
@ ghostdog74: Karena dia menerima jawaban ini, tampaknya di atas berhasil. Jika tidak, seperti yang Anda sebutkan di bawah, menambahkan -not -name "*.*"akan melakukan triknya.
Stephan202
62

ini akan mencari file tanpa ekstensi dan menambahkan .jpg Anda

find /path -type f -not -name "*.*" -exec mv "{}" "{}".jpg \;
anjing hantu74
sumber
Ini pasti akan memberikan hasil yang diinginkan 99% dari waktu. +1
les
9

Ini agak terlambat, tetapi saya pikir saya akan menambahkan bahwa solusi yang lebih baik (meskipun mungkin kurang terbaca) daripada yang sejauh ini mungkin:

find /path -type f -not -name "*.*" -print0 | xargs -0 rename 's/(.)$/$1.jpg/'

Menggunakan find | xargspola biasanya menghasilkan eksekusi yang lebih efisien, karena Anda tidak perlu melakukan proses baru untuk setiap file.

Perhatikan bahwa ini membutuhkan versi ganti nama yang ditemukan di distro rasa Debian (alias nama awal), daripada penggantian nama tradisional. Ini hanya skrip perl kecil, jadi akan cukup mudah untuk menggunakan perintah di atas pada sistem apa pun.

Chad Huneycutt
sumber
4

seperti ini,

for f in $(find . -type f); do mv $f ${f}.jpg; done

Saya tidak mengharapkan Anda memiliki nama file yang dipisahkan spasi,
Jika ya, nama-nama itu perlu diproses sedikit.

Jika Anda ingin menjalankan perintah dari direktori lain,
Anda dapat mengganti find .dengan find /target/directory.

nik
sumber
1
Ini kehilangan 'do' dan jika ada spasi di nama file, mungkin lebih baik mengutip nama file: untuk f di $ (find. -Type f); lakukan mv "$ f" "$ {f} .jpg"; selesai
DrAl
dan mungkin saya akan menjalankannya dari dalam direktori tingkat atas?
robjmills
@seengee: ya. Perhatikan bahwa perintah ini juga melewatkan tanda hubung di -type.
Stephan202
Saya harus pergi ke suatu tempat dan mengetik terlalu cepat ... memperbaiki sekarang.
nik
1

Untuk mengganti nama semua file yang tidak berekstensi di Windows basic bisa anda lakukan ren * *.jpg Karena file tersebut tidak berekstensi, cukup gunakan *, atau jika ingin merubah png ke jpg gunakanren *.png *.jpg

Nuno
sumber
0

rename

tidak yakin itu dapat mengganti nama file tanpa ekstensi (saya di windows 7 sekarang)

dfa
sumber
1
itu bisa, tetapi itu juga akan mengganti nama direktori, dan tidak ada cara untuk memberitahu itu untuk bekerja secara rekursif di sub-direktori (setidaknya dengan versi yang saya miliki di Ubuntu).
mirod
Saya tahu setidaknya dari dua perintah berbeda yang dipanggil rename, satu program C termasuk dalam util-linux-ng dan satu lagi program Perl (oleh Wall sendiri) di mesin Debian universitas kami. Sebenarnya, tidak satupun dari keduanya melakukan rekursi.
Boldewyn