एक regex से मेल खाने वाली उपनिर्देशिका का पुन: नाम बदलें


11

मेरे पास एक मीडिया सर्वर है जिसका नाम फ़ोल्डर है Series। ( /media/Expansion2/Series/)

इसमें, मेरे पास (आश्चर्य!) टीवी श्रृंखला है। ये सिर्फ शो के नाम हैं, जैसे,/media/Expansion2/Series/The Big Bang Theory/

प्रत्येक शो के फ़ोल्डर के अंदर (और यह वह जगह है जहाँ समस्या निहित है) मेरे पास सीजन फ़ोल्डर हैं। मेरे पास वर्तमान में निम्नलिखित 2 सम्मेलनों का मिश्रण है (कुछ और के साथ, शायद):

  1. /media/Expansion2/Series/The Big Bang Theory/The Big Bang Theory Season 1
  2. /media/Expansion2/Series/The Big Bang Theory/Season 2

अंत में, मैं सभी फ़ोल्डरों को सिर्फ नाम देना चाहता हूं Season #

एक रेगीक्स के रूप में, मैं शायद कुछ ऐसा कहूंगा s/.*(Season \d)/$1

केवल फ़ोल्डरों पर लागू होता है, फाइलों पर नहीं। मुझे शायद यह भी उल्लेख करना चाहिए कि यह लगभग 50+ शो उप फ़ोल्डर्स के लिए है, इसलिए इसे /media/Expansion2/Series/स्तर पर शुरू करने और प्रत्येक श्रृंखला में देखने की आवश्यकता है :)

जवाबों:


12

डेबियन और डेरिवेटिव पर (उबंटू सहित):

find /media/Expansion2/Series/ -type d -exec rename -n 's/.*(Season \d)/$1/' {} ";"

renameआदेश पर्ल पैकेज का हिस्सा है। यह अन्य वितरणों द्वारा प्रदान नहीं किया गया है, वे इसके बजाय मानक लिनक्स renameकमांड प्रदान करते हैं जो यहां उपयोगी नहीं है।

अगर rename -n(-तो वास्तव में) यह प्रदर्शित करता है कि वह क्या करना चाहता है, और यह आपके लिए बिल्कुल सही है, -n को छोड़ दें और ऐसा करें।


कहना चाहिए, मैंने पिछले कुछ दिनों में इस विधि को विशेष रूप से उपयोगी पाया है - न केवल फ़ोल्डरों के लिए, बल्कि फाइलों के लिए भी। धन्यवाद।
डेन्हम कोट

1
जहाँ तक मुझे याद है, उपकरण को renameडेबियन पर ही बुलाया जाता है । उबंटू (और कुछ स्वादों) पर, पहले उल्लेखित मानक renameकमांड के साथ नाम की गड़बड़ी से बचने के लिए , यह कभी-कभी (लेकिन हमेशा नहीं) के तहत पाया जाता है prename। यहां लुबंटू पर, टूल को ही कहा जाता है, prenameलेकिन इसे renameसिमलिंक चेन के कारण कहा जा सकता है /usr/bin/rename -> /etc/alternatives/rename -> /usr/bin/file-rename, जहां file-renameथोड़ा संशोधित संस्करण है prename
वाक्यविन्यास

बहुत बढ़िया! कि मुझे कई निर्देशिकाओं में कई फ़ाइलों के लिए किया है!
Eusoubrasileiro

2

निम्नलिखित स्निपेट कुछ भी Season [0-9]दिखाता है जो कि हर शो डायरेक्टरी में अंतिम घटना से पहले होता है /media/Expansion2/Series। कोई नियमित अभिव्यक्ति आवश्यक नहीं, बस ग्लब्स।

cd /media/Expansion2/Series
for show in ./*/; do
    (
        cd "$show" || { echo "cd failed.  Skipping $show"; exit 1; }
        for season in ./*Season\ [[:digit:]]*/; do
                season_prefix=${season%Season [[:digit:]]*}
                mv "$season" ./"${season#$season_prefix}"
        done
    )
done

2

आप इसे सुरक्षित खेलने के लिए और केवल नाम बदलने पसंद करते हैं some show/some show stuffकरने के लिए some show/stuff:

for d in */; do
  for f in "$d${d%/} *"; do
    mv "$f" "${d}${f%$d${d%/} }"
  done
done

यदि आप पहले सब कुछ छीनना चाहते हैं Season:

for x in */*Season*; do
  mv "$x" "${x%/*}/${x##*Season}Season"
done

${var#PATTERN}की शुरुआत में स्ट्राइकर पैटर्नन $varऔर परिणाम लौटाता है। ${var%PATTERN}अंत में ऐसा ही करता है। ${var#PATTERN}और ${var%PATTERN}क्रमशः सबसे छोटे मिलान उपसर्ग और प्रत्यय को हटा दें; ${var##PATTERN}और ${var%%PATTERN}सबसे लंबे मैच को हटा दें।


0

मैं इस उम्मीद में दो और समाधान पोस्ट करने जा रहा हूं कि वे भविष्य में मददगार हो सकते हैं। ये लिनक्स के काम में प्रवेश से आया था। बस यह दिखाने के लिए जाता है कि इस नाखून पर कितने हथौड़े काम करेंगे!

समाधान 1:

हाय डेनहम,

मैं यहाँ कुछ धारणाएँ बना रहा हूँ, उदाहरण के लिए कि "XXX सीजन #" के साथ निर्देशिका का हिस्सा हमेशा "बाहर" निर्देशिका (पत्ती नोड) होगा।

किसी भी मामले में, मैं थोड़ी स्क्रिप्ट लिखूंगा। कुछ इस तरह से काम करना चाहिए (चर में दोहरे उद्धरणों पर ध्यान दें, यह सुनिश्चित करने के लिए कि आप निर्देशिका में सभी स्थानों पर कब्जा कर लें):

find /media/Expansion2/Series/ -type d | while read olddir
do 
   newdir=`echo "${olddir}" | awk -F "/" '$NF ~ /Season/ { last=substr($NF,index($NF, "Season")); while (i<(NF-1)) { i++; printf("/%s", $i) }; printf("/%s\n", last) } $NF !~ /Season/ { print }'`
   if [ "${olddir}" != "${newdir}" ]
   then
       mv "${olddir}" "${newdir}"
   fi
done

बेशक, इससे पहले कि आप इसे "mv" $ {olddir} "" $ {newdir} "कमांड के साथ चलाएं, आपको यह सुनिश्चित करने के लिए" echo "$ {olddir}" "$ {newdir}" जैसी चीज़ डालनी चाहिए। आप जो परिणाम प्राप्त करने की उम्मीद करते हैं या आप एक और सिरदर्द के साथ समाप्त कर सकते हैं :-P


समाधान 2:

हाय डेनहम,

अधिकांश का उत्तर पहले से ही था। वैसे भी सीरीज फोल्डर से कुछ इस तरह से चलना ठीक काम करना चाहिए:

find -mindepth 2 -maxdepth 2 -type d | while read dir; do mv -T "$dir" "`dirname "$dir"`/`basename "$dir" | sed "s/.*Season \([0-9]*\)$/Season \1/i"`"; done  


स्पष्टीकरण:
• -mindepth 2 -maxdepth 2 -type d (सूची निर्देशिका दो स्तर नीचे)
• पढ़ते समय dir; (प्रत्येक dir पर लूप)
• mv -T "$ dir" (स्रोत dir को ... -T को एक त्रुटि प्राप्त करने की आवश्यकता है यदि सीज़न फ़ोल्डर अद्वितीय नहीं हैं, तो आपके पास "बिग बैंग थ्योरी सीजन" नहीं है 22 "और" सीज़न 22 "एक ही निर्देशिका में)
• dirname" $ ​​dir "वह पथ लौटाता है जहाँ dir है
• basename" $ ​​dir "निर्देशिका का नाम देता है
• sed" s /। सीज़न ([0-9]] ) $ / सीजन \ 1 / i "केस असंवेदनशील regexp के साथ जादू को पूरा करता है, बस मामले में।

मेरे छोटे परीक्षण में इसने काम किया (mv से पहले इसे प्रतिध्वनि के साथ आज़माएं):

someuser@linux-box:/tmp/Series$ find
.
./The Big Bang Theory
./The Big Bang Theory/Season 2
./The Big Bang Theory/Season 2/file1.avi
./The Big Bang Theory/Season 2/file 3.avi
./The Big Bang Theory/Season 2/file2.avi
./The Big Bang Theory/Season 2/file
./The Big Bang Theory/Season 2/3.avi
./The Big Bang Theory/The Big Bang Theory Season 1
./The Big Bang Theory/The Big Bang Theory Season 1/file1.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file 3.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file2.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file
./The Big Bang Theory/The Big Bang Theory Season 1/3.avi
./Other Series
./Other Series/Season 2
./Other Series/Stre dsfdf sd dSeason 3

someuser@linux-box:/tmp/Series$ find -mindepth 2 -maxdepth 2 -type d | while read dir; do mv -T "$dir" "dirname "$dir"/basename "$dir" | sed "s/.*Season \([0-9]*\)$/Season \1/i""; done
mv: ./The Big Bang Theory/Season 2' and./The Big Bang Theory/Season 2' are the same file
mv: ./Other Series/Season 2' and./Other Series/Season 2' are the same file

someuser@linux-box:/tmp/Series$ find
.
./The Big Bang Theory
./The Big Bang Theory/Season 2
./The Big Bang Theory/Season 2/file1.avi
./The Big Bang Theory/Season 2/file 3.avi
./The Big Bang Theory/Season 2/file2.avi
./The Big Bang Theory/Season 2/file
./The Big Bang Theory/Season 2/3.avi
./The Big Bang Theory/Season 1
./The Big Bang Theory/Season 1/file1.avi
./The Big Bang Theory/Season 1/file 3.avi
./The Big Bang Theory/Season 1/file2.avi
./The Big Bang Theory/Season 1/file
./The Big Bang Theory/Season 1/3.avi
./Other Series
./Other Series/Season 3
./Other Series/Season 2

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