सही फ़ाइल एक्सटेंशन


15

मेरे पास विभिन्न प्रकारों की लगभग 12000 छवियां हैं लेकिन उनमें से हर एक का नाम बदलकर * .jpg है।

अब मैं उन्हें उनके उचित विस्तार को वापस देना चाहता हूं, मैं यह कैसे कर सकता हूं


2
पुनरावर्ती, या "फ्लैट" निर्देशिका में?
याकूब वलिजम


1
@steeldriver बहुत करीब है, लेकिन उन फ़ाइलों का विस्तार नहीं होता है, यहाँ उनके पास गलत एक्सटेंशन है।
याकूब वलिजम

1
@JacobVlijm यही कारण है कि मैंने प्रश्न को एक डुप्लिकेट के रूप में ध्वजांकित नहीं किया: हालांकि उत्तर में प्रस्तावित विधियों का मान यहां है, IMHO
Steeldriver

@steeldriver मैं पूरी तरह से सहमत हूँ।
याकूब वलिजम

जवाबों:


22

आप इसे अपेक्षाकृत आसानी से बैश में कर सकते हैं:

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 / द्वारा अनुसरण किया जाता है, तो केवल निर्देशिकाएं और उपनिर्देशिकाएं मेल खाती हैं।


@AB अपडेट देखें यह **उपनिर्देशिकाओं में पुनरावृत्ति करने की अनुमति देता है।
टेराडॉन

प्रत्येक पंक्ति के अंत में वे अर्धविराम निरर्थक हैं, क्या वे नहीं हैं?
धान लांडौ

@PaddyLandau हाँ, मैं इसे एक लाइनर के रूप में परीक्षण कर रहा था और यहाँ स्पष्टता के लिए नई कड़ियाँ जोड़ीं। मैं उन्हें निकालना भूल गया। ध्यान दें कि वे गलत नहीं हैं, जैसा कि आप कहते हैं कि केवल अनावश्यक है।
टेराडॉन

महान, हालांकि fileयह हमेशा लगता है कि विस्तार को निर्दिष्ट नहीं करता है: यह foo.bourne-againउदाहरण के लिए यहां एक बैश फ़ाइल बदल रहा है !
कैम्पा

1
@ काम्पा नहीं, बिल्कुल नहीं। यह बाइनरी फ़ाइलों, सामान्य पाठ फ़ाइलों, पर्ल और पाइथन लिपियों के लिए फर्जी एक्सटेंशन भी जोड़ देगा और सूची जारी हो जाएगी। सवाल विशेष रूप से छवियों के बारे में पूछ रहा था और जो लोग अपने सामान्य एक्सटेंशन के समान नाम रखते हैं। याद रखें कि लिनक्स पर एक्सटेंशन वैकल्पिक हैं, बहुत कम अपवादों के साथ, वे वास्तव में कुछ भी नहीं करते हैं। वे उपयोगकर्ता को अपने डेटा को व्यवस्थित करने में मदद करते हैं, ओएस उनके बारे में परवाह नहीं करता है।
टेराडॉन

11

नीचे दी गई स्क्रिप्ट का उपयोग (पुनरावर्ती रूप से) गलत तरीके से सेट किए गए एक्सटेंशन .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)

कैसे इस्तेमाल करे

  1. स्क्रिप्ट को एक खाली फ़ाइल में कॉपी करें, इसे इस रूप में सहेजें rename.py
  2. इसे कमांड द्वारा चलाएं:

    python3 /path/to/rename.py <directory>
    

बैश आधारित समाधानों के विपरीत, सरल और आसानी से पढ़ने के लिए +1।
डेविड

3

नोट: मेरा दृष्टिकोण बहुत जटिल प्रतीत होता है। मैं आपकी जगह टेरडोन का जवाब पसंद करूंगा।


आप 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

ध्यान दें कि यह असंभावित मामले में टूट जाएगा कि किसी भी फ़ाइल नाम में newlines हैं।
टेराडॉन

@terdon हाँ, मैं सोच रहा था। दुर्भाग्य से मुझे कुछ पता नहीं है कि मैं क्या कर सकता हूं। क्या आप मदद कर सकते हैं?
एबी

मुझे नहीं पता कि यह कैसे ठीक से awk का उपयोग करना है। यह काम का सही साधन नहीं है। या तो find -exec bash -c "..."वहाँ सब कुछ का उपयोग करें और while read -d '' name typeफ़ाइल नाम और fileआउटपुट को विभाजित करने के लिए उपयोग करें और फिर $typeफ़ाइल प्रकार प्राप्त करने के लिए पार्स करें। वास्तव में इसके लायक नहीं, शुद्ध (ईश) बैश में इसे और अधिक आसानी से करने के लिए मेरा जवाब देखें।
टेराडॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.