लिनक्स: फ़ाइल का नाम बदलें, लेकिन विस्तार रखें?


10

विंडोज / डॉस में, मैं rename myfile.* yourfile.*नाम बदलने के लिए कह सकता हूं, लेकिन एक्सटेंशन को बनाए रख सकता हूं । कैसे लिनक्स पर पूरा किया है?

मैन पेज केवल यह बताता है कि एक्सटेंशन को कैसे बदलना है, लेकिन यह वही है जो मैं चाहता हूं।

बोनस:
मैं वास्तव में एक फोटो की निर्माण तिथि को इसके फाइलनाम में डालना चाहता हूं, जैसे कुछ पाने के लिए 20091231 2359 New Year.jpg। मुझे डर है कि मुझे इसे प्राप्त करने के लिए कुछ गैर-तुच्छ आदेशों की आवश्यकता है?

जवाबों:


14

यहाँ बोनस प्रश्न के लिए एक उत्तर है।

मैं वास्तव में एक फोटो बनाने की तारीख को इसके फ़ाइल नाम में डालना चाहता हूं, जैसे कि 20091231 2359 नए साल के लिए कुछ प्राप्त करना। jpg। मुझे डर है कि मुझे इसे प्राप्त करने के लिए कुछ गैर-तुच्छ आदेशों की आवश्यकता है?

मान लें कि आप EXIF ​​डेटा से फोटो की निर्माण तिथि लेना चाहते हैं, तो आपको उसके लिए एक अलग टूल की आवश्यकता होगी। सौभाग्य से यह पता चला है कि jheadजो आप चाहते हैं, उसके -nविकल्प के साथ एक तुच्छ तरीका प्रदान करता है ।

$ jhead -h
 [...]

 -n[format-string]

             Rename files according to date.  Uses exif date if present, file
             date otherwise.  If the optional format-string is not supplied,
             the format is mmdd-hhmmss.  If a format-string is given, it is
             is passed to the 'strftime' function for formatting
             In addition to strftime format codes:
             '%f' as part of the string will include the original file name
             [...]

यहाँ एक उदाहरण है:

$ jhead -n%Y-%m-%d-%f New_year.jpg   
New_year.jpg --> 2009-12-31-New_year.jpg

संपादित करें : बेशक, तस्वीरों के एक समूह के लिए ऐसा करने के लिए, यह कुछ इस तरह होगा:

$ for i in *jpg; do jhead -n%Y-%m-%d-%f $i; done

अपनी पसंद के अनुसार फ़ॉर्मेट करने की तारीख को ट्विस्ट करने date --helpके लिए, उदाहरण के लिए, आउटपुट पर नज़र डालें ; यह उपलब्ध प्रारूप कोड को सूचीबद्ध करेगा।

(jhead विभिन्न प्रणालियों के लिए व्यापक रूप से उपलब्ध है। यदि आप उबंटू या डेबियन पर हैं, तो बस sudo apt-get install jheadइसे स्थापित करने के लिए टाइप करें।)


1
मैंने जेहाद के बारे में नहीं सोचा था, केवल नाम, स्टेट और कट के बदसूरत संयोजन का। शानदार जवाब के लिए धन्यवाद!
तोरबेन गुंडोफ्टे-ब्रून

10

सिर्फ नाम बदलने वाले हिस्से के लिए, 'नाम बदलने' का कार्यक्रम काम करेगा। यह उस उदाहरण के समान है जिसे आपने मैन पेज में देखा था, बस चारों ओर स्विच किया गया था।

justin@eee:/tmp/q$ touch myfile.{a,b,c,d}
justin@eee:/tmp/q$ ls
myfile.a  myfile.b  myfile.c  myfile.d
justin@eee:/tmp/q$ rename -v s/myfile/yourfile/ myfile.*
myfile.a renamed as yourfile.a
myfile.b renamed as yourfile.b
myfile.c renamed as yourfile.c
myfile.d renamed as yourfile.d
justin@eee:/tmp/q$ ls
yourfile.a  yourfile.b  yourfile.c  yourfile.d
justin@eee:/tmp/q$ 

1
कुछ डिस्ट्रोस पर, इस पर्ल रीनेम प्रोग्राम को प्रेंम कहा जाता है।

यह वास्तव में उपयोगी है! मैं आश्चर्यचकित था कि "नाम बदलने" से पहले मुझे इस प्रकार के कितने प्रश्नों से गुजरना पड़ा। धन्यवाद।
alanning

7
betelgeuse:tmp james$ ls myfile.* yourfile.*
ls: yourfile.*: No such file or directory   
myfile.a    myfile.b
betelgeuse:tmp james$ for file
> in myfile.*
> do
> mv "${file}" "`echo $file | sed 's/myfile\./yourfile./'`"
> done
betelgeuse:tmp james$ ls myfile.* yourfile.*
ls: myfile.*: No such file or directory
yourfile.a  yourfile.b

कुंजी यह है कि, यदि आपने एक उदाहरण देखा है जो दिखाता है कि फ़ाइल नाम के एक भाग को रेगेक्स के साथ कैसे जोड़ा जाए, तो यह एकमात्र उदाहरण है जिसकी आपको आवश्यकता है। एक्सटेंशन का यूनिक्स फाइल सिस्टम पर कोई विशेष दर्जा नहीं है - वे सिर्फ उस फ़ाइलनाम का एक हिस्सा हैं जो एक .चरित्र के बाद होता है ।


1
यह मेरे सवाल का जवाब है। (लेकिन दूसरा जवाब मुझे वहां और तेज और आसान लगता है।)
तोरबेन गुंडोफ्टे-ब्रून

4
फोर्क + निष्पादित सेड की आवश्यकता नहीं है mv "$file" yourfile"${file#myfile}":। किसी भी आधुनिक बॉर्न जैसे शेल (या किसी POSIX शेल) पर काम करता है, लेकिन शायद वास्तविक बॉर्न शेल नहीं।
जून को क्रिस जॉन्सन

4

यहाँ फ़ाइल नाम में हेरफेर करने के लिए कुछ अलग तरीके हैं

for f in *.jpg
do
    mv "$f" "before_part${f%.*}after_part.${f##*.}"
    # OR mv "$f" "before_part$(basename "$f" ".jpg")after_part.jpg"
done

पैरामीटर विस्तार में mvआदेश काम इस प्रकार है:

${f%.*}- इसमें शामिल स्ट्रिंग के अंत से सबसे छोटे मिलान पैटर्न को हटा दें $f, इस मामले में अंतिम डॉट के बाद और सहित सब कुछ हटा दें। एकल का %अर्थ है "अंत से सबसे छोटा"।

${f##*.}- इसमें निहित स्ट्रिंग की शुरुआत से सबसे लंबे मिलान पैटर्न को हटा दें $f, इस मामले में अंतिम डॉट से पहले और सहित सब कुछ (इसमें कोई अन्य डॉट्स भी शामिल है)। डबल #( ##) का अर्थ है "शुरुआत से सबसे लंबा"।

इसलिए, उदाहरण के लिए, यदि $f"Foo.bar.baZ.jpg" शामिल है:

echo "${f%.*}"

देता है

Foo.bar.baZ

तथा

echo "${f##*.}"

देता है

jpg

तो mvकमान, एक बार विस्तारित की तरह दिखेगा:

mv "Foo.bar.baZ.jpg" "before_partFoo.bar.baZafter_part.jpg"

मैं वास्तव में फॉर लूप का उपयोग कर रहा था, लेकिन एमवी उदाहरण नहीं, क्योंकि मुझे यह समझ में नहीं आता है :-)
टोरेन गुंडोफ्टे-ब्रून

नोट: उन लोगों के अर्थ f%और f##उदाहरण के लिए यहाँ वर्णित हैं: tldp.org/LDP/abs/html/parameter-substitution.html
Torben Gundtofte-Bruun

3

लिनक्स में कोई फ़ाइल नाम एक्सटेंशन नहीं हैं।

फ़ाइल नाम से विशेष सब्सट्रिंग को काटने और उन तक पहुंचने के लिए नियमित अभिव्यक्तियों का उपयोग करें।

उदाहरण:

वास्तविक जीवन परिदृश्य: आप html को chm फ़ाइल से निकाल रहे हैं। विंडोज में फ़ाइलनाम केस-असंवेदनशील हैं, इसलिए लिनक्स में आपको टूटे हुए लिंक मिलेंगे। आपके पास index.HTML नाम की एक फ़ाइल है , लेकिन URL में href = "index.html" है। तो आपका लक्ष्य उनके लिए लिंक से मिलान करने के लिए फ़ाइलनाम को अनुकूलित करना है।

मान लें कि आपके पास एक चर में फ़ाइल नाम है:

FILENAME='index.HTML'

संस्करण 3.0 बैश के साथ शुरू करना स्वयं नियमित अभिव्यक्ति का समर्थन करता है, इसलिए आपको हेरफेर करने के लिए किसी अतिरिक्त टूल जैसे grep / sed / perl आदि की आवश्यकता नहीं है। निम्न उदाहरण स्ट्रिंग में बैक-एंड मैच के प्रतिस्थापन को दिखाता है:

echo ${FILENAME/%\.HTML/.html}

यदि आप चाहें तो मैच और रिप्लेसमेंट स्ट्रिंग्स पैराट्राइज्ड हो सकते हैं, यह स्क्रिप्ट लिखते समय अतिरिक्त लचीलापन प्रदान करता है। निम्न कोड स्निपेट समान लक्ष्य प्राप्त करता है:

match='\.HTML'
replacement='.html'
echo ${FILENAME/%$match/$replacement}

अतिरिक्त जानकारी के लिए बैश डॉक्स से परामर्श करें।


1
कोई उदाहरण, इन नियमित अभिव्यक्तियों पर?
ग्नूपी

+1। यह उत्तर अब बहुत उपयोगी है (संपादन के बाद) - मुझे नहीं पता था कि आप बैश में इस तरह के स्ट्रिंग हेरफेर कर सकते हैं।
जोनीक

वास्तव में, उदाहरण के साथ अब बहुत बेहतर है। +1
ग्नूपी


0

वहाँ हमेशा यह करने के लिए एक से अधिक तरीका है। मैंने निम्नलिखित लिपि को / usr / स्थानीय / बिन / मैरेन के रूप में रखा।

फिर फोटो फ़ाइलों वाली स्क्रिप्ट में, बस टाइप करें: मैरेन

तस्वीरों को स्केल करने के लिए स्क्रिप्ट में एक वैकल्पिक कमेंट-आउट सुविधा भी है (ImageMagick का उपयोग करके)।

आशा है कि यह कुछ लोगों के लिए उपयोगी है।

#!/usr/bin/perl
#
# mrename files
#
#
use strict;

# if no 2 args, use defaults
my $dir = ".";

# read in path from command line
$dir = $ARGV[0] if ( defined( $ARGV[0] ) && $ARGV[0] ne "" );

# read in directory contents
opendir( DIR, $dir );
my @files = readdir( DIR );
closedir( DIR );

# rename and/or scale each file in directory
my $number_of_files = scalar( @files );
my $curfile = 0;

foreach my $file( @files ) {
    # only rename and scale jpg/gif files
    if ( $file =~ /\w+\.(jpg)$/ ) {
        my $extension = $1;
        $extension =~ tr/A-Z/a-z/;
        my $full_filename = "$dir/$file";

        # get stats on file- specifically the last modified time
        (my $dev,my $ino,my $mode,my $nlink,my $uid,my $gid,my $rdev,my $size,
        my $atime,my $mtime,my $ctime,my $blksize,my $blocks) = stat($full_filename);

        # convert last-modified time from seconds to practical datetime terms
        (my $sec,my $min,my $hour,my $mday,my $mon,my $year,my $wday,my $yday,
        my $isdst) = localtime($mtime);

        ++$mon;
        $year += 1900;

        my $filecdate = sprintf( "m%04i%02i%02i_%02i%02i%02i.$extension", $year, $mon, $mday, $hour, $min, $sec );
        my $full_newfilename = "$dir/$filecdate";

        # to scale files, use imagemagick by using the command below instead of mv 
        #my $cmd = "convert $full_filename -resize $scale% $full_newfilename";
        my $cmd = "mv $full_filename $full_newfilename";
        system( $cmd );

        # update percentage done
        my $percent_done = sprintf( "%5.2lf", 100* (++$curfile) / $number_of_files );
        print "\r$percent_done%";
    }
}
print "\n";

0

आप -X/--keep-extensionविकल्प का उपयोग कर सकते हैं rename(संस्करण 1.600):

-X, --keep-extension Save and remove the last extension from a filename, if there is any. The saved extension will be appended back to the filename at the end of the rest of the operations.

rename मैक के लिए Homebrew और Linux से Linuxbrew (पाठ्यक्रम के अन्य स्थापित विकल्पों में से) के लिए उपलब्ध है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.