Saya memiliki sekitar 12000 gambar dari jenis file yang berbeda tetapi masing-masing dari mereka diganti namanya * .jpg.
Sekarang saya ingin memberi mereka ekstensi yang tepat kembali, bagaimana saya bisa melakukannya
Saya memiliki sekitar 12000 gambar dari jenis file yang berbeda tetapi masing-masing dari mereka diganti namanya * .jpg.
Sekarang saya ingin memberi mereka ekstensi yang tepat kembali, bagaimana saya bisa melakukannya
Jawaban:
Anda dapat melakukannya dengan relatif mudah di bash:
for f in *jpg; do
type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+')
mv "$f" "${f%%.*}.${type,,}"
done
Ini adalah ide yang sama dengan jawaban @ AB tetapi menggunakan shell shell sebagai gantinya find. Ini ${f%%.*}adalah nama file tanpa ekstensi. The -0dari fileperintah membuatnya mencetak \0setelah nama file yang kemudian kita gunakan untuk grepjenis file. Ini harus bekerja dengan nama file yang sewenang-wenang, termasuk yang berisi spasi, baris baru atau apa pun. Ini ${type,,}adalah trik untuk mendapatkan ekstensi huruf kecil. Itu akan dikonversi PNGmenjadi png.
Anda tidak mengatakan dalam pertanyaan Anda, tetapi jika Anda ingin ini bersifat rekursif dan turun ke subdirektori, Anda bisa menggunakan ini sebagai gantinya:
shopt -s globstar
for f in **/*jpg; do
type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+')
mv "$f" "${f%%.*}.${type,,}"
done
Opsi ini shopt -s globstarakan mengaktifkan bash's globstar yang memungkinkan **mencocokkan subdirektori:
globstar
Jika diatur, pola ** yang digunakan dalam konteks ekspansi pathname akan cocok dengan semua file dan nol atau lebih direktori dan subdirektori. Jika pola diikuti oleh a, hanya direktori dan subdirektori yang cocok.
**untuk muncul kembali ke dalam subdirektori.
filetidak selalu menentukan ekstensi itu tampaknya: itu mengubah file bash ke foo.bourne-againsini misalnya!
Script di bawah ini dapat digunakan untuk (secara rekursif) mengganti nama ekstensi yang salah diatur .jpg,, ke yang benar. Jika menemukan file yang tidak dapat dibaca, itu akan melaporkannya dalam output skrip.
Script menggunakan imghdrmodul, untuk mengenali jenis berikut: rgb, gif, pbm, pgm, ppm, tiff, rast, xbm, jpeg, bmp, png. Lebih lanjut tentang imghdrmodul di sini . Daftar dapat diperpanjang dengan lebih banyak jenis, seperti yang disebutkan dalam tautan.
Seperti itu, ia secara khusus mengganti nama file dengan ekstensi .jpg, sebagaimana disebutkan dalam pertanyaan. Dengan perubahan kecil, bisa cocok untuk mengubah nama ekstensi apa pun, atau serangkaian ekstensi tertentu, menjadi yang benar (atau tanpa ekstensi, seperti di sini ).
#!/usr/bin/env python3
import os
import imghdr
import shutil
import sys
directory = sys.argv[1]
for root, dirs, files in os.walk(directory):
for name in files:
file = root+"/"+name
# find files with the (incorrect) extension to rename
if name.endswith(".jpg"):
# find the correct extension
ftype = imghdr.what(file)
# rename the file
if ftype != None:
shutil.move(file, file.replace("jpg",ftype))
# in case it can't be determined, mention it in the output
else:
print("could not determine: "+file)
rename.pyJalankan dengan perintah:
python3 /path/to/rename.py <directory>
Catatan: Pendekatan saya tampaknya terlalu rumit. Saya lebih suka jawaban terdon di tempat Anda.
Anda dapat menggunakan perintah fileuntuk menentukan jenis file:
% file 20050101_14-24-37_330.jpg
20050101_14-24-37_330.jpg: JPEG image data, EXIF standard 2.2, baseline, precision 8, 1200x1600, frames 3
% file test.jpg
test.jpg: PNG image data, 1192 x 774, 8-bit/color RGBA, non-interlaced
Dengan informasi ini, file dapat diubah namanya:
Silakan lakukan tes sebelum Anda menerapkan perintah ke gambar Anda
find . -type f -iname "*.jpg" -print0 | xargs -0 -I{} file -F"<separator>" {} |
awk -F " image data" '{print $1}' |
awk -F"<separator> " '{
system("mv \""$1"\" $(dirname \""$1"\")/$(basename -s .jpg \"" $1 "\")."$2)
}'
Contoh
% find . -type f -name "*.jpg"
./test.jpg
./sub/20050101_14-24-37_330.jpg
% find . -type f -iname "*.jpg" -print0 | xargs -0 -I{} file -F"<separator>" {} | awk -F " image data" '{print $1}' | awk -F"<separator> " '{system ("mv \""$1"\" $(dirname \""$1"\")/$(basename -s .jpg \"" $1 "\")."$2)}'
% find . -type f -iname "*"
./test.PNG
./sub/20050101_14-24-37_330.JPEG
find -exec bash -c "..."dan lakukan segala sesuatu di sana atau gunakan while read -d '' name typeuntuk membagi nama file dan fileoutput dan kemudian parsing $typeuntuk mendapatkan tipe file. Tidak sepadan, lihat jawaban saya untuk melakukannya dengan lebih mudah di bash (ish) murni.