Farklı dosya türlerinde yaklaşık 12000 görüntüm var, ancak her biri * .jpg olarak yeniden adlandırıldı.
Şimdi onlara uygun uzantılarını geri vermek istiyorum, nasıl yapabilirim
Farklı dosya türlerinde yaklaşık 12000 görüntüm var, ancak her biri * .jpg olarak yeniden adlandırıldı.
Şimdi onlara uygun uzantılarını geri vermek istiyorum, nasıl yapabilirim
Yanıtlar:
Bunu bash'da nispeten kolayca yapabilirsiniz:
for f in *jpg; do
type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+')
mv "$f" "${f%%.*}.${type,,}"
done
Bu, @ AB'nin cevabı ile aynı fikirdir, ancak bunun yerine kabuk globları kullanmaktır find
. ${f%%.*}
Onun uzantısı olmadan dosya adıdır. -0
Arasında file
komuta bir baskı yapar \0
o zaman için kullandığınız dosya adından sonra grep
dosya türü. Bu, boşluk, yeni satır veya başka bir şey içerenler de dahil olmak üzere rastgele dosya adlarıyla çalışmalıdır. Küçük ${type,,}
harf uzantıları almak için bir hile. Bu dönüştürmek istiyorum PNG
için png
.
Sorunuzda söylemediniz, ancak bunun yinelemeli olması ve alt dizinlere inmesi gerekiyorsa, bunun yerine bunu kullanabilirsiniz:
shopt -s globstar
for f in **/*jpg; do
type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+')
mv "$f" "${f%%.*}.${type,,}"
done
shopt -s globstar
Sağlayan Bash'in globstar seçeneğini sağlayacak **
maç alt dizinleri:
globstar
Ayarlanırsa, yol adı genişletme bağlamında kullanılan model ** tüm dosyalarla ve sıfır veya daha fazla dizin ve alt dizinle eşleşir. Deseni bir / izliyorsa, yalnızca dizinler ve alt dizinler eşleşir.
**
dizinlere geri dönmeye izin verir .
file
zaman uzantıyı belirtmese de: foo.bourne-again
örneğin bir bash dosyasını buraya dönüştürüyor !
Aşağıdaki komut dosyası, yanlış ayarlanmış bir uzantıyı (yinelemeli olarak) doğru olana yeniden adlandırmak için kullanılabilir .jpg
. Okunamayan bir dosya bulursa, dosyayı komut dosyasının çıktısında bildirir.
Komut kullanmak imghdr
aşağıdaki türde tanımak, modül: rgb
, gif
, pbm
, pgm
, ppm
, tiff
, rast
, xbm
, jpeg
, bmp
, png
. Buradaimghdr
modül hakkında daha fazla bilgi . Liste, bağlantıda belirtildiği gibi daha fazla türde genişletilebilir.
Olduğu gibi, özellikle .jpg
soruda belirtildiği gibi uzantıya sahip dosyaları yeniden adlandırır . Küçük bir değişiklikle, herhangi bir uzantıyı veya belirli bir uzantı grubunu doğru olana yeniden adlandırmak uygun olabilir (veya burada olduğu gibi uzantı içermez ).
#!/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.py
Komut ile çalıştırın:
python3 /path/to/rename.py <directory>
Not: Yaklaşımım çok karmaşık görünüyor. Yerinizde terdons cevabını tercih ederim.
file
Dosya türünü belirlemek için komutu kullanabilirsiniz :
% 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
Bu bilgilerle dosyalar yeniden adlandırılabilir:
Komutu resimlerinize uygulamadan önce lütfen bir test yapın
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)
}'
Misal
% 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 "..."
orada her şeyi kullanın ve yapın ya while read -d '' name type
da dosya adını ve file
çıktısını bölmek ve sonra $type
dosya türünü almak için ayrıştırmak için kullanın. Gerçekten buna değmez, saf (ish) bash'da nasıl daha kolay yapılacağına dair cevabımı görün.