BASH: कई फ़ाइलों और निर्देशिकाओं के साथ काम करना


3

मुझे लगभग 100+ निर्देशिकाओं के 15 लॉट मिले हैं, विशेष रूप से छद्म कोड का उपयोग करके आप कैसे कर सकते हैं:

rename * *suffix  
rename * prefix*  
rename * CAPITALIZE*  

कई फ़ाइलों और निर्देशिकाओं के साथ काम करने के लिए विशिष्ट ट्यूटोरियल के लिए युक्तियां या लिंक की सराहना की जाएगी।

जवाबों:


5

कई लिनक्स / यूनिक्स सिस्टम एक साथ आते हैं renameया rename.plया prenameपर्ल स्क्रिप्ट है कि पर्ल भाव के माध्यम से नाम बदलने की अनुमति देता है। डेबियन सिस्टम पर, यह perlपैकेज के साथ स्थापित है ।

$ rename
Usage: rename [-v] [-n] [-f] perlexpr [filenames]

perlexprतर्क में जादू होता है । यह अनिवार्य रूप से एक छोटा सा कोड है जो प्रत्येक फ़ाइलनाम पर काम करेगा। आपको कोई लूप प्रदान करने की आवश्यकता नहीं है, बस कोड लिखें जो आपके इनपुट को वांछित आउटपुट में बदल देता है। (निश्चित रहें और अभिव्यक्ति को उद्धृत करें; मैं शेल-विस्तार से बचाने के लिए एकल-उद्धरण का उपयोग करता हूं जब तक कि यह बिल्कुल आवश्यक न हो।)

तो, आपके उदाहरणों के लिए:

  • नाम * * प्रत्यय

    $ rename 's/$/suffix/' *
              ^ ^  ^^^^
              | |    +-- your suffix goes here
              | +------- indicates end-of-string
              +--------- perl's substitution operator (s/from-regex/to/)
    
  • नाम बदलें * उपसर्ग *

    $ rename 's/^/prefix/' *
                ^  ^^^^
                |    +-- your prefix goes here
                +------- indicates beginning-of-string
    
  • नाम बदलें * CAPIZIZE *

    $ rename '$_ = uc' *
              ^^^^ ^^
               |    +-- perl builtin function to capitalize a string
               +------- replaces input filename
    

O'Reilly Unix Power Tools पुस्तक के और उदाहरण देखें ।


लेकिन, देखभाल के साथ, यह सब एक ऑपरेशन में किया जा सकता है!
जोनाथन लेफलर

ज़रूर! मैं तीन अलग-अलग उदाहरण मानता हूं, एक उदाहरण में तीन ऑपरेशन नहीं।
क्वाट

यदि आप अपने द्वारा उपयोग किए जा रहे रेगेक्स के बारे में अनिश्चित हैं, तो झंडे -vऔर जोड़ दें -n, जो कि होने वाले नाम दिखाएगा, लेकिन वास्तव में उन्हें प्रदर्शन नहीं करेगा।
एंड्रयू फेरियर

2

यह सभी फ़ाइल नामों के लिए उपसर्ग और प्रत्यय जोड़ के लिए काम करेगा।

find / base / dir / path -type f -exec mv {} उपसर्ग {} प्रत्यय \;
# - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^

कैपिटलाइज़ेशन के लिए आप शायद एक छोटा bashलूप लिख सकते sedहैं जो अक्षर मामले को बदलने और फिर स्थानांतरित करने के लिए कुछ का उपयोग करेगा ।

मैं पढ़ने का सुझाव दूंगा,

  1. उन्नत बैश स्क्रिप्टिंग गिल
  2. पर्ल स्क्रिप्टिंग

2

मैं पर्ल का उपयोग करूंगा - और विशेष रूप से यह एक 'नाम बदलने' की स्क्रिप्ट का संशोधित संस्करण है जो ऊंट पुस्तक के 1 संस्करण में था (लेकिन स्थान की कमी के लिए दूसरे और तीसरे संस्करण से हटा दिया गया था)।

उपयोग:

find . -type f -print0 | xargs -0 rename 's%/([^/]+)$%/prefix\U${1}\Esuffix%'

जिसका अनुवाद किया जा रहा है, जिसका अर्थ है:

  • सभी फाइलें, यहां तक ​​कि उनके नाम के रिक्त स्थान को भी खोजें, और उन्हें ठीक से संभाल लें।
  • प्रत्येक फ़ाइल नाम के लिए, अंतिम स्लैश के बाद नाम ढूंढें, इसे '$ {1}' के रूप में याद रखें।
  • नाम को 'उपसर्ग' से बदलें, जो याद किया गया था, उसका ऊपरी-केस संस्करण और 'प्रत्यय'

तो, पूरी नौकरी एक पर्याप्त बहुमुखी उपकरण के साथ एक कमांड में की जा सकती है।


#!/Users/jleffler/perl/v5.10.0/bin/perl -w
#
# @(#)$Id: rename.pl,v 1.7 2008/02/16 07:53:08 jleffler Exp $
#
# Rename files using a Perl substitute or transliterate command

use strict;
use Getopt::Std;

my(%opts);
my($usage) = "Usage: $0 [-fnxV] perlexpr [filenames]\n";
my($force) = 0;
my($noexc) = 0;
my($trace) = 0;

die $usage unless getopts('fnxV', \%opts);

if ($opts{V})
{
    printf "%s\n", q'RENAME Version $Revision: 1.7 $ ($Date: 2008/02/16 07:53:08 $)';
    exit 0;
}
$force = 1 if ($opts{f});
$noexc = 1 if ($opts{n});
$trace = 1 if ($opts{x});

my($op) = shift;
die $usage unless defined $op;

if (!@ARGV) {
    @ARGV = <STDIN>;
    chop(@ARGV);
}

for (@ARGV)
{
    if (-e $_ || -l $_)
    {
        my($was) = $_;
        eval $op;
        die $@ if $@;
        next if ($was eq $_);
        if ($force == 0 && -f $_)
        {
            print STDERR "rename failed: $was - $_ exists\n";
        }
        else
        {
            print "+ $was --> $_\n" if $trace;
            print STDERR "rename failed: $was - $!\n"
                unless ($noexc || rename($was, $_));
        }
    }
    else
    {
        print STDERR "$_ - $!\n";
    }
}

जो कुछ भी इसके लायक है, मैं एक लगातार असफलता में भाग गया, जब मैंने कोशिश की तो यह भयानक रूप से सूचनात्मक नहीं था:

$ find . -type f -print0 | xargs -0 rename 's/.*/prefix$&suffix/'
rename failed: ./xxx-32 - No such file or directory
rename failed: ./xxx-64 - No such file or directory
rename failed: ./xxx.c - No such file or directory
rename failed: ./xxx.c~ - No such file or directory
$

यह अजीब था - मैं उन फाइलों को देख सकता हूं ...

'-X' विकल्प का उपयोग करके 'नाम बदलना' ने मुझे बताया कि परेशानी क्या थी, हालांकि:

rename failed: ./xxx-32 - No such file or directory
rename failed: ./xxx-64 - No such file or directory
rename failed: ./xxx.c - No such file or directory
rename failed: ./xxx.c~ - No such file or directory
+ ./xxx-32 --> prefix./xxx-32suffix
+ ./xxx-64 --> prefix./xxx-64suffix
+ ./xxx.c --> prefix./xxx.csuffix
+ ./xxx.c~ --> prefix./xxx.c~suffix

ओह ठीक है - 'उपसर्ग' नामक एक उप-निर्देशिका नहीं है। मेरी वर्तमान निर्देशिका में!


+1 के लिएfind -print0 | xargs -0
क्रिस जॉन्सन

@ जोनाथन लेफ़लर: मुझे लगता है कि आपने मुझे आशीर्वाद दिया है और तड़पाया है, क्योंकि आपकी स्क्रिप्ट एक गॉडसमेंड है ... फिर भी मुझे लगता है कि मुझे एक और भाषा सीखनी चाहिए, जिसका नाम है पर्ल, तुरंत। :) आपका बहुत बहुत धन्यवाद।
एंडी टर्नर

1

कैप्स-टू-लोअरकेस के बारे में, कैसे:

for filename in *                # Traverse all files in directory.
do
   fname=`basename $filename`
   n=`echo $fname | tr A-Z a-z`  # Change name to lowercase.
   if [ "$fname" != "$n" ]       # Rename only files not already lowercase.
   then
     mv $fname $n
   fi  
done   

लिनक्स डॉक्युमेंटेशन प्रोजेक्ट से बेशर्मी से चोरी: http://tldp.org/LDP/abs/html/textproc.html

पर्ल का उपयोग करने की तुलना में आसान (और संसाधन-हल्का) होना चाहिए।


1
यह फ़ाइलों के नाम नहीं बदलेगा, बस फ़ाइलों की सामग्री को अपरकेस (और डंप करने के लिए डंप करें)।
क्रिस जॉन्सन

0

मुझे पर्ल renameसबसे अच्छा लगता है, अगर आपके पास यह है या इसे प्राप्त कर सकते हैं।

यहाँ कुछ उत्तर भिन्नताएँ दी गई हैं:

# take out the echo to make these do the work

# find + xargs + bash (v4) + mv
# requires bash 4 for the ^^ uppercasing feature
find * -type f -print0 | xargs -0 bash -c 'for f in "$@"; do dir="";case "$1" in (*/*) dir="${f%/*}/";;esac;filename="${f##*/}"; echo mv "$f" "$dir${filename^^}"; done' mv

# find + xargs + sh + dirname + basename + tr + mv
# maybe easier to understand than above, but noticeably slower due to 3 forks per file
find * -type f -print0 | xargs -0 sh -c 'for f in "$@"; do echo mv "$f" "$(dirname "$f")/$(printf "$(basename "$f")" | tr "[:lower:]" "[:upper:]")"; done' mv

मैं zshहाल ही में चारों ओर से खेल रहा हूं , इसलिए यहां zmvचालान हैं:

# If the command line shell is not zsh, the prefix each of these commands with
#    zsh -fc 'autoload -U zmv && zmv $@'
# take the -n off to make it do the work instead of just talk about it

zmv -Qn '(**/)(*)(.)' '${1}prefix${2}'
zmv -Qn '(**/)(*)(.)' '${1}${2}suffix'
zmv -Qn '(**/)(*)(.)' '${1}${(U)2}'
# without the (.) qualifier (and the enabling -Q), dirs are processed also
zmv -n '(**/)(*)' '${1}prefix${2}'
zmv -n '(**/)(*)' '${1}${2}suffix'
zmv -n '(**/)(*)' '${1}${(U)2}'

0

यह पुनर्नामित पर्ल लिपि बाकी तर्कों के साथ दी गई फ़ाइलों का नाम बदलने के लिए कोड के रूप में पहले तर्क का मूल्यांकन करती है।

#!/usr/bin/perl

($op = shift) || die "Usage: $0 perlexpr [filenames]\n";
if (!@ARGV) {
    @ARGV = <STDIN>;
    chop(@ARGV);
}
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.