मेरे पास विभिन्न प्रकारों की लगभग 12000 छवियां हैं लेकिन उनमें से हर एक का नाम बदलकर * .jpg है।
अब मैं उन्हें उनके उचित विस्तार को वापस देना चाहता हूं, मैं यह कैसे कर सकता हूं
मेरे पास विभिन्न प्रकारों की लगभग 12000 छवियां हैं लेकिन उनमें से हर एक का नाम बदलकर * .jpg है।
अब मैं उन्हें उनके उचित विस्तार को वापस देना चाहता हूं, मैं यह कैसे कर सकता हूं
जवाबों:
आप इसे अपेक्षाकृत आसानी से बैश में कर सकते हैं:
for f in *jpg; do
type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+')
mv "$f" "${f%%.*}.${type,,}"
done
यह @ एबी के जवाब के समान है लेकिन इसके बजाय शेल ग्लब्स का उपयोग करना है find
। ${f%%.*}
इसके विस्तार के बिना फ़ाइल नाम है। -0
के file
आदेश यह एक प्रिंट बनाता है \0
फ़ाइल नाम है जिन्हें हम करने के लिए उपयोग करने के बाद grep
फ़ाइल प्रकार। यह मनमाना फ़ाइल नामों के साथ काम करना चाहिए, जिसमें रिक्त स्थान, नई सूची या कुछ भी शामिल है। ${type,,}
लोअर केस एक्सटेंशन प्राप्त करने के लिए एक चाल है। यह बदल जाएगा PNG
करने के लिए png
।
आपने अपने प्रश्न में नहीं कहा, लेकिन यदि आपको पुनरावर्ती होने और उपनिर्देशिका में उतरने की आवश्यकता है, तो आप इसके बजाय इसका उपयोग कर सकते हैं:
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
सक्षम हो जाएगा जो की सुविधा देता है बैश के globstar विकल्प **
मैच उपनिर्देशिका:
globstar
यदि सेट किया जाता है, तो पथनाम विस्तार संदर्भ में प्रयुक्त पैटर्न ** सभी फाइलों और शून्य या अधिक निर्देशिकाओं और उपनिर्देशिकाओं से मेल खाएगा। यदि पैटर्न a / द्वारा अनुसरण किया जाता है, तो केवल निर्देशिकाएं और उपनिर्देशिकाएं मेल खाती हैं।
**
उपनिर्देशिकाओं में पुनरावृत्ति करने की अनुमति देता है।
file
यह हमेशा लगता है कि विस्तार को निर्दिष्ट नहीं करता है: यह foo.bourne-again
उदाहरण के लिए यहां एक बैश फ़ाइल बदल रहा है !
नीचे दी गई स्क्रिप्ट का उपयोग (पुनरावर्ती रूप से) गलत तरीके से सेट किए गए एक्सटेंशन .jpg
को सही करने के लिए किया जा सकता है। यदि यह एक अपठनीय फ़ाइल पाता है, तो यह इसे स्क्रिप्ट के आउटपुट में रिपोर्ट करेगा।
स्क्रिप्ट का उपयोग imghdr
मॉड्यूल, निम्न प्रकार की पहचान करने के लिए: rgb
, gif
, pbm
, pgm
, ppm
, tiff
, rast
, xbm
, jpeg
, bmp
, png
। यहाँimghdr
मॉड्यूल पर अधिक । सूची को और अधिक प्रकारों के साथ बढ़ाया जा सकता है, जैसा कि लिंक में बताया गया है।
जैसा कि यह है, यह विशेष .jpg
रूप से एक्सटेंशन के साथ फ़ाइलों का नाम बदलता है , जैसा कि प्रश्न में उल्लेख किया गया है। एक मामूली बदलाव के साथ, यह किसी भी एक्सटेंशन, या एक्सटेंशन के एक विशिष्ट सेट को सही एक में बदलने के लिए फिट हो सकता है (या यहां बिना किसी एक्सटेंशन के )।
#!/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
इसे कमांड द्वारा चलाएं:
python3 /path/to/rename.py <directory>
नोट: मेरा दृष्टिकोण बहुत जटिल प्रतीत होता है। मैं आपकी जगह टेरडोन का जवाब पसंद करूंगा।
आप 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
इस जानकारी के साथ, फ़ाइलों का नाम बदला जा सकता है:
कृपया अपनी छवियों पर कमांड लागू करने से पहले एक परीक्षण करें
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 -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 "..."
वहाँ सब कुछ का उपयोग करें और while read -d '' name type
फ़ाइल नाम और file
आउटपुट को विभाजित करने के लिए उपयोग करें और फिर $type
फ़ाइल प्रकार प्राप्त करने के लिए पार्स करें। वास्तव में इसके लायक नहीं, शुद्ध (ईश) बैश में इसे और अधिक आसानी से करने के लिए मेरा जवाब देखें।