मैं लिनक्स पर लोअरकेस करने के लिए सभी फ़ोल्डर्स और फ़ाइलों का नाम कैसे बदलूं?


179

मुझे एक पूर्ण फ़ोल्डर ट्री को फिर से नाम बदलना है ताकि कोई अपरकेस अक्षर कहीं भी प्रकट न हो (यह C ++ स्रोत कोड है, लेकिन यह कोई बात नहीं होनी चाहिए)।

सीवीएस और तोड़फोड़ संस्करण नियंत्रण फ़ाइलों / फ़ोल्डरों की अनदेखी के लिए बोनस अंक। पसंदीदा तरीका एक शेल स्क्रिप्ट होगा, क्योंकि शेल किसी भी लिनक्स बॉक्स पर उपलब्ध होना चाहिए।

फ़ाइल का नाम बदलने के विवरण के बारे में कुछ मान्य तर्क थे।

  1. मुझे लगता है कि समान लोअरकेस नामों वाली फाइलें अधिलेखित होनी चाहिए; यह उपयोगकर्ता की समस्या है। जब एक मामले की अनदेखी करने वाले फ़ाइल सिस्टम पर जाँच की जाती है, तो यह पहले वाले को बाद वाले के साथ अधिलेखित कर देगा।

  2. मैं AZ वर्णों पर विचार करूंगा और उन्हें az में बदल दूंगा, बाकी सब सिर्फ समस्याओं के लिए बुला रहा है (कम से कम स्रोत कोड के साथ)।

  3. लिनक्स सिस्टम पर एक बिल्ड को चलाने के लिए स्क्रिप्ट की आवश्यकता होगी, इसलिए मुझे लगता है कि सीवीएस या तोड़फोड़ संस्करण नियंत्रण फ़ाइलों में परिवर्तन को छोड़ दिया जाना चाहिए। सब के बाद, यह सिर्फ एक खरोंच जांच है। शायद एक "निर्यात" अधिक उपयुक्त है।


पहले से पोस्ट किया गया बॉक्स पूरी तरह से या साधारण मामलों के लिए कुछ समायोजन के साथ काम करेगा, लेकिन बैच का नाम बदलने से पहले कुछ परिस्थितियां हैं जिन्हें आप ध्यान में रखना चाहते हैं: 1. यदि आपके पास दो या दो से अधिक नाम हैं तो क्या होना चाहिए पथ पदानुक्रम में समान स्तर जो केवल मामले से भिन्न होता है, जैसे कि ABCdef, abcDEFऔर aBcDeF? नाम बदलने के लिए गर्भपात करना चाहिए या सिर्फ चेतावनी देना चाहिए और जारी रखना चाहिए? 2. आप गैर यूएस-एएससीआईआई नामों के लिए निचले मामले को कैसे परिभाषित करते हैं? यदि ऐसे नाम मौजूद हो सकते हैं, तो क्या पहले एक चेक और बहिष्कृत पास होना चाहिए? 3. यदि आप नाम बदलने का अभियान चला रहे हैं
Mihai Limbă Sepan

जवाबों:


179

"rename"कमांड का उपयोग करते हुए संक्षिप्त संस्करण :

find my_root_dir -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

यह फ़ाइलों से पहले नाम बदला जा रहा है और गैर-मौजूदा निर्देशिका (जैसे "A/A"में "a/a") में फ़ाइलों को स्थानांतरित करने की कोशिश कर रहा है के साथ समस्याओं से बचा जाता है ।

या, उपयोग किए बिना एक अधिक वर्बोज़ संस्करण "rename"

for SRC in `find my_root_dir -depth`
do
    DST=`dirname "${SRC}"`/`basename "${SRC}" | tr '[A-Z]' '[a-z]'`
    if [ "${SRC}" != "${DST}" ]
    then
        [ ! -e "${DST}" ] && mv -T "${SRC}" "${DST}" || echo "${SRC} was not renamed"
    fi
done

पुनश्च

उत्तरार्द्ध चाल कमांड के साथ अधिक लचीलेपन की अनुमति देता है (उदाहरण के लिए, "svn mv")।


36
नाम का उपयोग इस तरह से किया जा सकता है और साथ ही नाम बदलकर 'y / AZ / az /' *
Tzury Bar Yochay

3
खबरदार, दोनों संस्करण असंवेदनशील फाइलसिस्टम पर काम नहीं करेंगे। मेरे मामले में मैंने then-enclosed लाइन को बदल दिया (mv "${SRC}" "${DST}.renametmp" && mv "${DST}.renametmp" "${DST}") || echo "${SRC} was not renamed"
ल्लोकी

6
रिक्त स्थान (संदर्भ: linux, bash) युक्त फ़ाइलों के साथ दूसरा दृष्टिकोण मेरे लिए सही ढंग से काम नहीं करता था।
मंद

4
नाम बदलने के अंतिम संस्करण का उपयोग करते हुए, किसी भी रेगेक्स की आवश्यकता नहीं है। पूरा कमांड बन जाता है find my_root_dir -depth -exec rename -c {} \;। नाम बदलने के लिए -f जोड़े यदि आप एक केस-संवेदी फाइल सिस्टम (जैसे मैक) पर हैं
Javache

दूसरे ने कमान -Tसे हटाकर सोलारिस पर मेरे लिए काम किया mv
हाम

261

छोटे अभी भी मुझे काफी पसंद है:

rename 'y/A-Z/a-z/' *

OS X के HFS + जैसे असंवेदनशील फाइल सिस्टम के मामले में , आप -fध्वज जोड़ना चाहेंगे :

rename -f 'y/A-Z/a-z/' *

3
linux.icydog.net/rename.php :The renaming utility that comes by default with Ubuntu is a Perl program sometimes called prename
sleepsort

1
धन्यवाद, मैंने इसे इस तरह से इस्तेमाल किया $ खोज | xargs का नाम बदलकर 'y / AZ / az /' *
Rashi

5
यह मानता है कि आपके पास पर्ल्स का नाम है, जो हमेशा ऐसा नहीं होता है। उदाहरण के लिए, मेरे डेबियन का नाम पूरी तरह से अलग है
क्रिज़िस्तोफ क्रेसो

10
आर्क पर, कार्यक्रम कहा जाता है perl-rename(और एक ही नाम के साथ एक पैकेज द्वारा प्रदान किया जाता है)
jaymmer - Reinstate Monica

3
यह दी गई समस्या का उत्तर नहीं देता है क्योंकि "नाम बदलना" पुनरावर्ती नहीं है।
15

89
for f in `find`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done

कृपया अपनी स्क्रिप्ट चलाने से पहले एक "mkdir -p A / B / C" करें।
tzot 10

2
"खोज" को आपके द्वारा नाम बदलने की इच्छा वाली फ़ाइलों की एक सूची प्राप्त करने के लिए जो भी आदेश का उपयोग किया जाना चाहिए; उदाहरण के लिए, "ls *। {C, CPP, H}"।
जेपीगेट

2
ओएस एक्स पर काम नहीं करता है, बस के लिए उपयोग जानकारी प्रिंट करता है findfind .इसे ठीक करने के लिए लगता है।
इमलाई

3
सभी टिप्पणियों से "समेकित" संस्करण, (उत्तर अब संपादित नहीं किया जा सकता है):for f in `find .`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done
romaricdrigon

1
क्या कोई मुझे समझा सकता है कि यह पहली जगह में क्यों काम करना चाहिए? यदि यह पाता है ।/FOO और ./FOO/BAR, यह पहले नाम बदल देता है ।/FOO to / .foo, जिसके बाद यह अब नहीं मिल सकता है ।/FOO/BAR नीचे अपना जवाब दर्ज करके इसे ठीक करना चाहिए।
oisyn

80

यदि आपको दक्षता की परवाह करने की आवश्यकता नहीं है, तो बस निम्नलिखित का प्रयास करें।

zip -r foo.zip foo/*
unzip -LL foo.zip

13
वाह, यह एक बहुत ही अक्षम तरीका है।
Artjom B.

28
यह मानते हुए कि कम्प्यूटेशनल दक्षता आमतौर पर एक चिंता का विषय नहीं है जब आप खुद को एक निर्देशिका में फ़ाइलों का नाम बदलने की जरूरत महसूस करते हैं ... मुझे लगता है कि यह संभवतः इस थ्रेड पर सबसे रचनात्मक सरल समाधान है। वास्तव में कुछ इस तुच्छ को स्वीकार किए गए उत्तरों को प्रदर्शित करने के रूप में जटिल नहीं होना चाहिए और यह वर्कअराउंड इस तरह के ऑपरेशन में निवेश करने की मेरी सोच की मात्रा के अनुपात में बहुत अधिक है। +1000
पीटर एम। एलियास

27
आप इसे में तेजी लाने के कर सकते हैं के साथ -0(जो की 'शून्य', कोई संपीड़न) स्विच, zip -0 -r foo.zip foo/
जॉनी बालोनी

3
मुझे 50'000 से अधिक फ़ाइलनामों को विभिन्न निर्देशिका संरचनाओं में बदलना पड़ा। मूल स्वीकार किए गए उत्तर ने 2 मिनट में बमुश्किल 10% काम किया, जहां -0संपीड़न के साथ यह लगभग तुरंत था!
चपरासी

2
यह सिर्फ अक्षम नहीं है। यह केवल एक असंभव है अगर एक अस्थायी संग्रह के लिए पर्याप्त खाली स्थान नहीं है।
विक्टर यारमा

19

यार, तुम लोग / लड़कियों को उलझी हुई चीजें खत्म करना पसंद करते हो ... का प्रयोग करें:

rename 'y/A-Z/a-z/' *

2
यह काम नहीं करता है, यह कहता है कि लोअरकेस नाम वाली फ़ाइल पहले से मौजूद है।
किर्गॉफ

@kirhgoff मैंने देखा है कि एनएफएस आरोह के साथ होता है - यहां दिए गए निर्देशों का पालन करें
जोबेन्सन

हम केस-संवेदी फाइलसिस्टम का नाम कैसे बदल सकते हैं? rename 'y/a-z/A-Z/' /tmp/*.jpg-> Can't rename /tmp/*.jpg /TMP/*.JPG: No such file or directory, यानी, केवल फ़ाइल के बजाय पूरे पथ का नाम बदलने का प्रयास करें।
पाब्लो ए

14

ऊपर दिए गए अधिकांश उत्तर खतरनाक हैं, क्योंकि वे विषम अक्षरों वाले नामों से नहीं निपटते हैं। इस तरह की चीज़ के लिए आपका सबसे सुरक्षित दांव find's' -print0विकल्प का उपयोग करना है , जो \ n के बजाय ASCII NUL के साथ फ़ाइलनाम को समाप्त करेगा।

यहाँ एक स्क्रिप्ट है, जो केवल फाइलों को बदल देती है और निर्देशिका के नाम को भ्रमित नहीं करती है find:

find .  -type f -print0 | xargs -0n 1 bash -c \
's=$(dirname "$0")/$(basename "$0");
d=$(dirname "$0")/$(basename "$0"|tr "[A-Z]" "[a-z]"); mv -f "$s" "$d"'

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

touch \;\ echo\ hacker::0:0:hacker:\$\'\057\'root:\$\'\057\'bin\$\'\057\'bash

... अच्छा अंदाजा लगाए ...


इसके renameबजाय उपयोग करना अधिक सरल होगा mv
विक्टर यारेमा

14

यह तब काम करता है जब आपके पास पहले से ही नाम बदलें या सेट करें (जैसे मैक में ब्रू इंस्टॉल के माध्यम से ):

rename --lower-case --force somedir/*

9
... यदि आप नाम पहले सेट करते हैं, उदाहरण के लिएbrew install rename
pduersteler

3
'y / AZ / az /' *
स्टीफन

4
--lower-case? कम से कम दुख की बात है कि आर्क लिनक्स में ऐसा नहीं है।

3
renameबैश बिलिन नहीं है। यह एक बाहरी उपयोगिता है और आपके द्वारा इंस्टॉल किए गए संस्करण के आधार पर सिंटैक्स अलग होगा। यह उत्तर एक पोर्टेबल समाधान के रूप में "सभी यूनिक्स आधारित ओएस के लिए पर्याप्त नहीं है" जैसा कि दावा किया गया है।
कोरी गोल्डबर्ग

2
बस जाँच की जाती है, पैकेज के renameमाध्यम से नवीनतम फेडोरा (28) में शामिल कमांड util-linux-2.31का --lower-caseविकल्प नहीं है ।
niXar सेप

11

यह पर्ल स्क्रिप्ट के बिना CentOS / Red Hat Linux या अन्य वितरण पर काम करता है rename:

for i in $( ls | grep [A-Z] ); do mv -i "$i" "`echo $i | tr 'A-Z' 'a-z'`"; done

स्रोत: अपरकेस से लेकर लोअरकेस वर्ण तक सभी फ़ाइल नामों का नाम बदलें

(कुछ वितरणों में डिफॉल्ट renameकमांड उपयोग-लिनेक्स से आता है, और यह एक अलग, असंगत उपकरण है।)


यह केवल एकल निर्देशिका पर काम करता है, पुनरावर्ती रूप से नहीं
ब्रैम

कोल .. अच्छी तरह से काम करता है
मणिकंदन राम

6

मैक ओएस एक्स पर मुझे मिला सबसे सरल तरीका http://plasmasturm.org/code/rename/ से नाम बदलने के पैकेज का उपयोग करना था :

brew install rename
rename --force --lower-case --nows *

- नाम बदलें जब भी गंतव्य नाम के साथ एक फ़ाइल पहले से मौजूद है।

- लोअर-केस सभी निचले केस में फ़ाइल नाम बदलें।

- नन एकल अंडरस्कोर वर्णों के साथ फ़ाइल नाम में व्हॉट्सएप के सभी दृश्यों को बदलें।


5

यहां बैश शेल स्क्रिप्ट का उपयोग करते हुए मेरा उप-अपनाने वाला समाधान दिया गया है:

#!/bin/bash
# First, rename all folders
for f in `find . -depth ! -name CVS -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming folder $f"
      mv -f "$f" "$g"
   fi
done

# Now, rename all files
for f in `find . ! -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming file $f"
      mv -f "$f" "$g"
   fi
done

फ़ोल्डर सभी को सही ढंग से नाम दिया गया है, और mv जब अनुमतियाँ मेल नहीं खाती हैं, और सवाल नहीं पूछ रही हैं, और सीवीएस फ़ोल्डर का नाम नहीं बदला गया है (उस फ़ोल्डर के अंदर सीवीएस नियंत्रण फाइलें अभी भी बदली हैं, दुर्भाग्य से)।

चूंकि "find -depth" और "find | Sort -r" दोनों ही फ़ोल्डर सूची को नाम बदलने के लिए उपयोग करने योग्य क्रम में वापस कर देते हैं, मैंने फ़ोल्डर्स खोजने के लिए "-depth" का उपयोग करना पसंद किया।


आपकी पहली खोज काम नहीं करती है। "Mkdir -p A / B / C" आज़माएं और फिर अपनी स्क्रिप्ट चलाएं।
tzot

4

मूल प्रश्न एसवीएन और सीवीएस निर्देशिकाओं की अनदेखी करने के लिए कहा गया है, जो कि खोज कमांड में -prune जोड़कर किया जा सकता है। सीवीएस की अनदेखी करने के लिए:

find . -name CVS -prune -o -exec mv '{}' `echo {} | tr '[A-Z]' '[a-z]'` \; -print

[संपादित करें] मैंने इसे आज़माया, और निम्न-केस अनुवाद को खोज के अंदर एम्बेड करना उन कारणों से काम नहीं किया जिन्हें मैं वास्तव में नहीं समझता। इसलिए, इसमें संशोधन करें:

$> cat > tolower
#!/bin/bash
mv $1 `echo $1 | tr '[:upper:]' '[:lower:]'`
^D
$> chmod u+x tolower 
$> find . -name CVS -prune -o -exec tolower '{}'  \;

इयान


4

लैरी वाल के फ़ाइल नाम फिक्सर का उपयोग करना:

$op = shift or die $help;
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}

यह उतना ही सरल है

find | fix 'tr/A-Z/a-z/'

(जहां fixस्क्रिप्ट ऊपर है)


3

यह एक छोटी सी शेल स्क्रिप्ट है जो आपके द्वारा अनुरोधित है:

root_directory="${1?-please specify parent directory}"
do_it () {
    awk '{ lc= tolower($0); if (lc != $0) print "mv \""  $0 "\" \"" lc "\"" }' | sh
}
# first the folders
find "$root_directory" -depth -type d | do_it
find "$root_directory" ! -type d | do_it

पहली खोज में -depth कार्रवाई पर ध्यान दें।


1
केवल एक चीज जो पूरे धागे से मैक पर काम करती है। बहुत बहुत धन्यवाद!
यमलसैट

2

पोर्टेबल नहीं, केवल Zsh, लेकिन बहुत संक्षिप्त।

पहले, सुनिश्चित करें zmvकि लोड किया गया है।

autoload -U zmv

यह भी सुनिश्चित करें कि extendedglob:

setopt extendedglob

फिर उपयोग करें:

zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'

उन फ़ाइलों और निर्देशिकाओं का पुनरावर्तन करने के लिए जहां नाम CVS नहीं है ।


2
for f in `find -depth`; do mv ${f} ${f,,} ; done

find -depthप्रत्येक फ़ाइल और निर्देशिका को प्रिंट करता है, निर्देशिका के पहले ही निर्देशिका की सामग्री मुद्रित होती है। ${f,,}फ़ाइल नाम को कम करता है।


यह काम नहीं करता है: यह सामग्री पर संचालित होने से पहले एक निर्देशिका का नाम बदल देता है, जैसे कि सामग्री पर बाद का प्रयास विफल हो जाता है।
छँटाई

-depthफिक्स को जोड़ना ! यह वास्तव में एक त्वरित समाधान है, लेकिन निश्चित रूप से इसका उपयोग किए बिना-print0 से खोजने विकल्प , यह सबसे विश्वसनीय नहीं है
jpaugh

@jpaugh नहीं यह नहीं है। यह नाम बदलने का प्रयास करेगा ।/FOO/BAR to ./foo/bar, लेकिन ./oo उस समय तक मौजूद नहीं है।
oisyn

2

MacOS के साथ,

renameपैकेज स्थापित करें ,

brew install rename

उपयोग,

find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"                       

यह कमांड सभी फाइलों को *.pyएक्सटेंशन के साथ ढूंढती है और फाइलनाम को लोअर केस में परिवर्तित करती है।

`f` - forces a rename

उदाहरण के लिए,

$ find . -iname "*.py" -type f
./sample/Sample_File.py
./sample_file.py
$ find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"
$ find . -iname "*.py" -type f
./sample/sample_file.py
./sample_file.py

आपने यहां -Iविकल्प का उपयोग क्यों किया xargs?
विक्टर यारेमा

- Iझंडा अनिवार्य नहीं है। इसका उपयोग तब किया जाता है जब हम कई कमांड को निष्पादित करते हैं xargs। यहाँ xargs cat foo.txt | xargs -I % sh -c 'echo %; mkdir %' आप के साथ कई आदेशों का उपयोग करने का एक उदाहरण दिया जा सकता है -Iजैसेfind . -iname "*.py" -type f | xargs -I% rename -c -f "%"
akilesh raj

2

टाइपसेट का उपयोग करें :

typeset -l new        # Always lowercase
find $topPoint |      # Not using xargs to make this more readable
  while read old
  do new="$old"       # $new is a lowercase version of $old
     mv "$old" "$new" # Quotes for those annoying embedded spaces
  done

Windows पर, Git Bash जैसे इम्यूलेशन विफल हो सकते हैं क्योंकि Windows हुड के नीचे केस-संवेदी नहीं है। उन लोगों के लिए, एक कदम जोड़ें mvजो फ़ाइल को किसी अन्य नाम से पहले, जैसे "$ old.tmp", और फिर $new


1

लंबा लेकिन "कोई आश्चर्य और कोई प्रतिष्ठान के साथ काम करता है"

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

# adapt the following command _IF_ you want to deal with specific files/dirs
find . -depth -mindepth 1 -exec bash -c '
  for file do
    # adapt the awk command if you wish to rename to something other than lowercase
    newname=$(dirname "$file")/$(basename "$file" | awk "{print tolower(\$0)}")
    if [ "$file" != "$newname" ] ; then
        # the extra step with the temp filename is for case-insensitive filesystems
        if [ ! -e "$newname" ] && [ ! -e "$newname.lcrnm.tmp" ] ; then
           mv -T "$file" "$newname.lcrnm.tmp" && mv -T "$newname.lcrnm.tmp" "$newname" 
        else
           echo "ERROR: Name already exists: $newname"
        fi
    fi    
  done
' sh {} +

संदर्भ

मेरी स्क्रिप्ट इन उत्कृष्ट उत्तरों पर आधारित है:

/unix/9496/looping-through-files-with-spaces-in-the-names

बैश में लोअर केस में स्ट्रिंग कैसे कन्वर्ट करें?


1

यह macOS पर भी अच्छी तरह से काम करता है:

ruby -e "Dir['*'].each { |p| File.rename(p, p.downcase) }"

यह विशेष रूप से अच्छा है क्योंकि मैक्सी के साथ रूबी जहाजों।
jxmorris12

1

मुझे विंडोज 7 पर सिगविन सेटअप पर ऐसा करने की आवश्यकता थी और मैंने पाया कि मुझे ऊपर दिए गए सुझावों के साथ वाक्यविन्यास त्रुटियां मिलीं, जो मैंने कोशिश कीं (हालांकि मैं एक काम करने का विकल्प याद कर सकता हूं)। हालांकि, उबंटू मंचों से सीधे यह समाधान कैन से बाहर काम कर गया :-)

ls | while read upName; do loName=`echo "${upName}" | tr '[:upper:]' '[:lower:]'`; mv "$upName" "$loName"; done

(एनबी: मैंने पहले व्हाट्सएप को अंडरस्कोर के साथ बदल दिया था:

for f in *\ *; do mv "$f" "${f// /_}"; done

)


1

ओएस एक्स में, mv -f"एक ही फ़ाइल" त्रुटि दिखाता है, इसलिए मैं दो बार नाम बदलता हूं:

for i in `find . -name "*" -type f |grep -e "[A-Z]"`; do j=`echo $i | tr '[A-Z]' '[a-z]' | sed s/\-1$//`; mv $i $i-1; mv $i-1 $j; done

1

मैं इस स्थिति में पायथन के लिए पहुंचूंगा, ताकि बिना स्पेस या स्लैश के आशावादी रास्ते से बचा जा सके। मैंने यह भी पाया है कि python2अधिक से अधिक स्थानों पर स्थापित किया जा सकता है rename

#!/usr/bin/env python2
import sys, os

def rename_dir(directory):
  print('DEBUG: rename('+directory+')')

  # Rename current directory if needed
  os.rename(directory, directory.lower())
  directory = directory.lower()

  # Rename children
  for fn in os.listdir(directory):
    path = os.path.join(directory, fn)
    os.rename(path, path.lower())
    path = path.lower()

    # Rename children within, if this child is a directory
    if os.path.isdir(path):
        rename_dir(path)

# Run program, using the first argument passed to this Python script as the name of the folder
rename_dir(sys.argv[1])

इसे जटिल बनाने के बारे में बात करें ... बस करो .. नाम बदलकर 'y / AZ / az /' *
स्टीफन

1
@Stephen, कि आप का नाम बदलने के लिए व्यवस्थापक पहुँच है मान लेता है। मुझे अक्सर सिस्टम पर डेटा को मून करने की आवश्यकता होती है, जिस पर मेरे पास अन्य सॉफ़्टवेयर स्थापित करने की क्षमता नहीं है। हाल के उबंटू में, यह केवल तभी स्थापित होता है जब पर्ल मौजूद होता है।
जॉन फोली

1

यदि आप आर्क लिनक्स का उपयोग करते हैं , तो आप उस renameसे पैकेज को स्थापित कर सकते हैं ) कमांड को निष्पादन योग्य और एक मैनुअल पेजAUR प्रदान करता हैrenamexm/usr/bin/renamexm उसके साथ।

यह फ़ाइलों और निर्देशिकाओं का तेज़ी से नाम बदलने के लिए एक बहुत शक्तिशाली उपकरण है।

लोअरकेस में बदलें

rename -l Developers.mp3 # or --lowcase

UPPER मामले में कनवर्ट करें

rename -u developers.mp3 # or --upcase, long option

अन्य विकल्प

-R --recursive # directory and its children

-t --test # Dry run, output but don't rename

-o --owner # Change file owner as well to user specified

-v --verbose # Output what file is renamed and its new name

-s/str/str2 # Substitute string on pattern

--yes # Confirm all actions

आप यहाँ से नमूना Developers.mp3 फ़ाइल प्राप्त कर सकते हैं , यदि आवश्यक हो;)


1
brewmacOS पर नाम बदलने से -lएक सिमलिंक बनाने, और -cलोअरकेस में कनवर्ट करने के लिए बाध्य हो गया है , इसलिए बाहर देखें।
rien333

0
( find YOURDIR -type d | sort -r;
  find yourdir -type f ) |
grep -v /CVS | grep -v /SVN |
while read f; do mv -v $f `echo $f | tr '[A-Z]' '[a-z]'`; done

पहले निर्देशिकाओं का नाम बदलकर सॉर्ट करें -r (जहां -depth उपलब्ध नहीं है), फिर फाइलें। फिर grep -v / CVS खोजने के बजाय ... - prune क्योंकि यह सरल है। बड़ी निर्देशिकाओं के लिए, f में ... कुछ शेल बफ़र्स को ओवरफ़्लो कर सकता है। का उपयोग करें ... | पढ़ते समय बचने के लिए ।

और हां, यह क्लॉबर फाइलें होंगी जो केवल मामले में भिन्न होती हैं ...


पहला: find YOURDIR -type d | sort -rबहुत ज्यादा परेशानी है। आप चाहते हैं find YOURDIR -depth -type d। दूसरा, find -type fनिर्देशिकाओं का नाम बदलने के बाद MUST रन होना चाहिए।
tzot

0
find . -depth -name '*[A-Z]*'|sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'|sh

मैंने यहाँ वर्णित अधिक विस्तृत लिपियों की कोशिश नहीं की है, लेकिन मेरे Synology NAS पर मेरे लिए एक भी कमांडलाइन संस्करणों ने काम नहीं किया है। renameउपलब्ध है, और के रूपांतरों के कई नहीं है find, क्योंकि यह पहले से ही नाम दिया गया पथ (उदाहरण के पुराने नाम से चिपक यदि यह पाता है लगता है असफल ./FOOद्वारा पीछा किया ./FOO/BAR, का नाम बदलने ./FOOके लिए ./fooअभी भी सूची के लिए जारी रहेगा./FOO/BAR , भले ही उस पथ अब मान्य नहीं है) । ऊपर की कमान ने बिना किसी मुद्दे के मेरे लिए काम किया।

निम्नानुसार कमांड के प्रत्येक भाग की व्याख्या है:


find . -depth -name '*[A-Z]*'

यह किसी भी फाइल को करंट डाइरेक्टरी ( .जो भी डायरेक्टरी आप प्रोसेस करना चाहते हैं उसे बदल सकते हैं), एक डीप-फर्स्ट सर्च (उदाहरण के लिए, यह ./foo/barपहले लिस्ट होगी) का उपयोग करके मिलेगा ./foo, लेकिन केवल उन फाइलों के लिए जिनमें अपरकेस कैरेक्टर होता है। -nameफिल्टर केवल आधार फ़ाइल नाम, नहीं पूरा पथ पर लागू होता है। तो यह सूची होगी ./FOO/BARलेकिन नहीं ./FOO/bar। यह ठीक है, क्योंकि हम नाम नहीं बदलना चाहते हैं ./FOO/bar। हम ./FOOहालांकि नाम बदलना चाहते हैं , लेकिन यह बाद में सूचीबद्ध है (यह इसलिए -depthमहत्वपूर्ण है)।

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


sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'

यह भाग findआउटपुट की गई फ़ाइलों को पढ़ता है और उन्हें mvएक नियमित अभिव्यक्ति का उपयोग करके कमांड में प्रारूपित करता है । -nविकल्प बंद हो जाता है sedइनपुट मुद्रण से, और pखोज एवं प्रतिस्थापन regex आउटपुट प्रतिस्थापित पाठ में आदेश।

रेगेक्स में ही दो कैद होते हैं: अंतिम / (जो फ़ाइल की निर्देशिका है) तक का हिस्सा है, और फ़ाइल नाम स्वयं। निर्देशिका को बरकरार रखा गया है, लेकिन फ़ाइल नाम को लोअरकेस में बदल दिया गया है। तो, अगर findआउटपुट ./FOO/BAR, यह हो जाएगा mv -n -v -T ./FOO/BAR ./FOO/bar। यह सुनिश्चित करता है कि मौजूदा लोअरकेस फ़ाइलों का -nविकल्प mvओवरराइट नहीं किया गया है। -vविकल्प बनाता है mvहर बदलाव है कि यह बनाता है (- अगर या नहीं पड़ता है उत्पादन ./FOO/barपहले से मौजूद है, यह की तरह कुछ आउटपुट ./FOO/BAR -> ./FOO/BAR, यह देखते हुए कि कोई परिवर्तन नहीं किया गया है)। -Tयहाँ बहुत महत्वपूर्ण है - यह एक निर्देशिका के रूप में लक्ष्य फ़ाइल व्यवहार करता है। इससे यह सुनिश्चित हो जाएगा कि अगर उस निर्देशिका का अस्तित्व ./FOO/BARनहीं है तो उसे स्थानांतरित नहीं किया जाएगा ./FOO/bar

findइसे निष्पादित करने वाली कमांड की एक सूची उत्पन्न करने के लिए एक साथ उपयोग करें (वास्तव में इसे किए बिना क्या किया जाएगा यह सत्यापित करने के लिए आसान है)


sh

यह बहुत आत्म व्याख्यात्मक है। यह सभी उत्पन्न mvकमांड को शेल दुभाषिया के लिए रूट करता है । आप इसे bashअपनी पसंद के किसी भी शेल के साथ बदल सकते हैं।


0

नाम बदलें (regex)

यह बिल्कुल वैसा नहीं है जैसा ओपी ने पूछा था, लेकिन मैं इस पेज पर क्या पाने की उम्मीद कर रहा था:

फ़ाइलों के नाम बदलने के लिए एक "सुस्त" संस्करण, ताकि वे URL के समान हों (अर्थात केवल अल्फ़ान्यूमेरिक, डॉट्स और डैश शामिल हों):

rename "s/[^a-zA-Z0-9\.]+/-/g" filename

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