Рекурсивно перейменуйте підкаталоги, які відповідають регексу


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

На Debian та похідних (включаючи Ubuntu):

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

renameКоманда є частиною пакета Perl. Це не передбачено іншими дистрибутивами, вони натомість надають стандартну renameкоманду Linux, яка тут не корисна.

Якщо rename -n(-не насправді) відображається те, що він хоче зробити, і для вас це все добре, опустіть -n і вкажіть це.


Потрібно сказати, що я знайшов цей метод особливо корисним протягом останніх днів - не лише для папок, але й для файлів. Дякую.
Денхем Кут

1
Наскільки я пам’ятаю, інструмент викликається лишеrename в Debian . Для Ubuntu (та деяких ароматів), щоб уникнути зіткнень з іменами із згаданою раніше стандартною командою, її іноді (але не завжди) можна знайти під . Тут, на Lubuntu, називається сам інструмент, але він може бути названий за рахунок ланцюга symlink , де є дещо змінена версія . renameprenameprenamerename/usr/bin/rename -> /etc/alternatives/rename -> /usr/bin/file-renamefile-renameprename
синтаксичний помилок

приголомшливий! Це змусило мене зробити це для декількох файлів у кількох каталогах!
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}смужки PATTERN на початку $varта повертає результат. ${var%PATTERN}робить те саме в кінці. ${var#PATTERN}і ${var%PATTERN}видалити відповідно найкоротший відповідний префікс і суфікс; ${var##PATTERN}і ${var%%PATTERN}вилучіть найдовший збіг.


0

Я збираюся розмістити ще два рішення з надією, що вони можуть бути корисними в майбутньому. Вони надійшли від адміністраторів Linux на роботі. Просто іде показати, скільки молотків буде працювати на цьому цвяху!

Рішення 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 -тип d (перерахуйте каталоги на два рівні вниз)
• під час читання dir; (цикл на кожен dir)
• mv -T "$ dir" (перемістіть джерело dir до ... -T потрібно, щоб отримати помилку, якщо папки сезону не унікальні, тобто у вас немає "Теорія великого вибуху" 22 "та" Сезон 22 "у тому самому каталозі)
• ім'я" $ dir "повертає шлях, де знаходиться dir
• базове ім'я" $ dir "повертає ім'я каталогу
• sed" s /. Season ([0-9] ) $ / Сезон \ 1 / i "завершує магію з нечутливим випадком повторного виведення, про всяк випадок.

У моєму маленькому тесті це спрацювало (спробуйте спочатку з відлунням перед 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 та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.