Скрипт BASH для рекурсивной сортировки файлов по базовому имени файла в папки с тем же именем

#bash #shell #scripting #file #directory

#bash #оболочка #скриптинг #файл #каталог

Вопрос:

У меня есть следующая структура файла:

ПРИВЕТ

  • ActionPotential_hi.mp4
  • ADHD_hi.mp4
  • Болезнь Альцгеймера_хи.mp4
  • alzheimers_art_hi.mp4
  • artificial_eye_hi.mp4
  • больше файлов

LO

  • ActionPotential_lo.mp4
  • ADHD_lo.mp4
  • Болезнь Альцгеймера_lo.mp4
  • alzheimers_art_lo.mp4
  • artificial_eye_lo.mp4
  • и т.д.

MED

*base_filename*_med.mp4

КАДРЫ

*base_filename*_med.jpg

CAPTIONS

*base_filename*.adb.xml

TRANSCRIPTS

*base_filename*.txt

Чтобы загрузить их в среду MarkLogic, мне нужно, чтобы они были преобразованы в следующую структуру, где asset — это базовое имя файла.

ASSET

  • asset_lo.mp4
  • asset_med.mp4
  • asset_hi.mp4
  • asset.txt
  • asset.adb.xml
  • asset_med.jpg

Я хотел бы, чтобы скрипт bash отсортировал их для меня. Предложения?

Ответ №1:

 find . -type f -print |
while read -r pathname; do
    filename=${pathname##*/}
    case "$filename" in
        *_hi* | *_med* | *_lo*)
            # strip off last underscore and following chars
            new_dirname=${filename%_*} 
            ;;
        *)
            # strip off first dot and following chars
            new_dirname=${filename%%.*} 
            ;;
    esac
    mkdir -p "../$new_dirname"
    echo mv "$pathname" "../$new_dirname/$filename"
done 
  

Непроверено. Удалите, echo когда убедитесь, что mv команды выглядят корректно.

Я переместил целевые каталоги в родительский каталог CWD, потому что я не уверен, find будут ли загружены вновь созданные каталоги. Кто-нибудь может затронуть этот вопрос?

Комментарии:

1. @glenn выглядит многообещающе, я тестирую сегодня вечером.

2. @glenn jackman: это хорошо работает, когда у меня есть только каталоги с файлами mp4. Я получаю что-то вроде mv ./hi/ADHD_hi.mp4 .././hi/ADHD/ADHD_hi.mp4 Но когда я добавляю папки xml и txt, я получаю mv ./captions/artificial_eye.adb.xml ..//artificial_eye.adb.xml , что неправильно. Не перемещается в эту папку с базовым именем. Я думаю, что ваш скрипт написан не для того, чтобы иметь дело с «adb.xml «файлы. Я поиграю и посмотрю, смогу ли я разобраться в этом, но любые дальнейшие указания приветствуются!

3. @two7s_clash, правильно. В *) ветви инструкции case он находит первую точку в качестве первого символа. Я обновлю свой ответ через несколько минут

4. нет, не работает для файлов типа CAPTIONS/artificial_eye.adb.xml (или даже artificial_eye.xml ) или TRANSCRIPTS/artificial_eye.txt

5. @glenn: Я запустил это по-настоящему this AM и обнаружил, что чего-то не заметил. Это не помещает все в один и тот же каталог с базовым именем для каждой группы файлов. Например. В итоге я получаю /captions/ADHD/ADHD.xml и /txt/ADHD/ADHD.txt . Каждая из них по-прежнему находится под родительским именем «captions» или «txt». Я хочу, чтобы txt-файл и XML-файл (и другие файлы) находились в одном каталоге ADHD, вот так: /ADHD/ADHD.xml и /ADHD/ADHD.txt