เปลี่ยนชื่อไดเรกทอรีย่อยซ้ำ ๆ ที่ตรงกับ 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 #ในท้ายที่สุดผมต้องการที่จะเปลี่ยนชื่อโฟลเดอร์ทั้งหมดเพียง

เป็น regex ฉันอาจจะพูดอะไรบางอย่างเช่น s/.*(Season \d)/$1

ใช้ได้กับโฟลเดอร์เท่านั้นไม่ใช่ไฟล์ ฉันควรจะพูดถึงว่านี่เป็นโฟลเดอร์ย่อยประมาณ 50+ รายการดังนั้นจึงต้องเริ่มที่/media/Expansion2/Series/ระดับและดูในแต่ละซีรีย์ :)

คำตอบ:


12

บน Debian และอนุพันธ์ (รวมถึง Ubuntu):

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

renameคำสั่งเป็นส่วนหนึ่งของแพคเกจ Perl มันไม่ได้จัดเตรียมโดยการแจกแจงอื่น แต่ให้renameคำสั่งLinux มาตรฐานแทนซึ่งไม่มีประโยชน์ที่นี่

หากrename -n(- ไม่จริง) แสดงสิ่งที่ต้องการทำและมันเหมาะกับคุณให้ละเว้น -n และทำให้มันเกิดขึ้น


ต้องบอกว่าฉันได้พบวิธีนี้มีประโยชน์อย่างยิ่งในช่วงสองสามวันที่ผ่านมา - ไม่เพียง แต่สำหรับโฟลเดอร์เท่านั้น แต่ยังรวมถึงไฟล์ด้วย ขอบคุณ
Denham Coote

1
เท่าที่ผมจำได้ว่าเครื่องมือที่เรียกว่าrenameใน Debian เท่านั้น บน Ubuntu (และรสชาติพอใช้) เพื่อที่จะหลีกเลี่ยงการปะทะกันชื่อกับมาตรฐานดังกล่าวก่อนหน้าrenameคำสั่งมันเป็นบางครั้ง ( แต่ไม่เสมอไป) prenameอยู่ภายใต้ ที่นี่ใน Lubuntu เครื่องมือของตัวเองที่เรียกว่าprenameแต่มันอาจจะเรียกว่าเป็นrenameเนื่องจากห่วงโซ่ symlink /usr/bin/rename -> /etc/alternatives/rename -> /usr/bin/file-renameซึ่งเป็นรุ่นที่แก้ไขเล็กน้อยfile-rename prename
ไวยากรณ์

! น่ากลัว นั่นทำให้ฉันทำอย่างนั้นสำหรับหลาย ๆ ไฟล์ในหลาย ๆ ไดเรกทอรี!
eusoubrasileiro

2

ต่อไปนี้อะไรแถบตัวอย่างข้อมูลที่เกิดขึ้นก่อนที่จะเกิดขึ้นครั้งล่าสุดของในไดเรกทอรีแสดงทุกภายใต้Season [0-9] /media/Expansion2/Seriesไม่จำเป็นต้องมีการแสดงออกปกติเพียงแค่ globs

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}ตัด PATTERN ที่จุดเริ่มต้น$varและส่งคืนผลลัพธ์ ${var%PATTERN}ทำเช่นเดียวกันในตอนท้าย ${var#PATTERN}และ${var%PATTERN}ลบคำนำหน้าการจับคู่ที่สั้นที่สุดและคำต่อท้ายตามลำดับ; ${var##PATTERN}และ${var%%PATTERN}ลบการแข่งขันที่ยาวที่สุด


0

ฉันจะโพสต์โซลูชันสองรายการเพิ่มเติมโดยหวังว่าพวกเขาจะมีประโยชน์ในอนาคต สิ่งเหล่านี้มาจากผู้ดูแลระบบ Linux ในที่ทำงาน เพียงไปเพื่อแสดงจำนวนค้อนจะทำงานกับเล็บนี้!

โซลูชันที่ 1:

สวัสดีเดนแฮม

ฉันต้องตั้งสมมติฐานบางอย่างที่นี่เช่นส่วนของไดเรกทอรีที่มี "XXX Season #" จะเป็นไดเรกทอรี "นอก" เสมอ (โหนดปม)

ไม่ว่าในกรณีใดฉันจะเขียนบทเล็กน้อย สิ่งนี้ควรใช้งานได้ (สังเกตเครื่องหมายอัญประกาศคู่รอบตัวแปรเพื่อให้แน่ใจว่าคุณได้จับช่องว่างทั้งหมดในไดเรกทอรี):

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:

สวัสดีเดนแฮม

คำตอบส่วนใหญ่อยู่ในคำถามแล้ว อย่างไรก็ตามการทำงานบางอย่างเช่นรายการต่อไปนี้จากโฟลเดอร์ 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  


คำอธิบาย:
• find -mindepth 2 -maxdepth 2 -type d (แสดงรายการไดเร็กทอรีสองระดับ)
•ขณะที่อ่าน dir; (วนรอบแต่ละ dir)
• mv -T "$ dir" (ย้าย dir ต้นทางไปที่ ... - T จำเป็นต้องได้รับข้อผิดพลาดหากโฟลเดอร์ Season ไม่ซ้ำกันนั่นคือคุณไม่มี "The Big Bang Theory Season 22 "และ" Season 22 "ในไดเรกทอรีเดียวกัน)
• dirname" $ ​​dir "ส่งคืนพา ธ ที่ dir คือ
• basename" $ ​​dir "ส่งคืนชื่อของไดเรกทอรี
• sed" s /. Season ([0-9] ) $ / Season \ 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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.