Как сделать сценарий оболочки для перемещения файлов в отдельные папки на основе имени файла?

Я хочу автоматизировать движущиеся файлы эпизода сериала в отдельные каталоги для каждого эпизода.

По существу в папке я хочу запустить скрипт в, у меня есть список файлов. Например: tvshow.2009.S01E01.episodename1.mkv, tvshow.2009.S01E02.episodename2.mkv, tvshow.2009.S01E03.episodename3.mkv, ect. и пустые каталоги в формате E01, E02, E03, ect.

Я перемещал файлы вручную в эту точку с помощью автозавершения Вкладки в командной строке. По существу я ввожу:

mv t

и затем поражая клавишу Tab для автоматического заполнения к

mv tv.show.2009.S01E0

затем введите 1 и Вкладка снова для получения до

mv tv.show.2009.S01E01.episodename1.mkv 

затем я ввожу корректную папку для получения до

mv tv.show.2009.S01E01.episodename1.mkv E01/

и затем хит Входит для завершения команды. Я должен повторить шаги для стольких же эпизодов, сколько я имею в исходном каталоге, и, учитывая факт я по существу повторяю те же шаги и просто выполняю итерации числа эпизода, это походит на идеальное использование для цикла в сценарии.

Проблема - то, что файлы находятся не всегда в том же формате и будут, очевидно, иметь различные имена в зависимости от шоу. Что является постоянным, хотя это S##E## будет всегда появляться в имени файла, и я только должен использовать E## определить корректный файл и переместить его в папку, которая уже существует и точно соответствует E## из файла.

Я - опытный программист, но еще не работал со сценариями оболочки. Моя мысль состоит в том, чтобы, возможно, выполнить итерации через все существующее E## папки, ищите файл, который содержит это E## последовательность, и затем перемещает тот файл в папку. К сожалению, я не уверен корректный подход в выполнении этого со сценарием, что я могу работать на командной строке.

Кто-либо имел бы предложенный план подхода или смог бы указать на меня к ресурсу, к которому я мог обратиться для справки?

1
задан 15 November 2019 в 00:06

4 ответа

Можно использовать это из каталога, где у Вас есть свои файлы и пустые каталоги, если Ваши файлы имеют .mkv расширение:

for file in *.mkv;do mv "$file" "$(echo $file | sed -E 's/.*S[0-9]+(E[0-9]+).*/\1/')";done

В вышеупомянутом for цикл, mv используется для перемещения каждого файла ("$file") в соответствующий каталог ("$(echo $file | sed -E 's/.*S[0-9]+(E[0-9]+).*/\1/')") эпизода. Здесь, sed используется для извлечения эпизода из имени файла. По существу это соответствует S##E## часть имени файла с помощью регулярного выражения (.*S[0-9]+(E[0-9]+).*), от которого только часть в круглых скобках сохранена (\1 в конце [1 115] команда).

Начальная файловая структура:

.
├── E01
├── E02
├── E03
├── E04
├── E05
├── tv.show.2009.S01E01.episodename1.mkv
├── tv.show.2009.S01E02.episodename1.mkv
├── tv.show.2009.S01E03.episodename1.mkv
├── tv.show.2009.S01E04.episodename1.mkv
└── tv.show.2009.S01E05.episodename1.mkv

Результат:

.
├── E01
│   └── tv.show.2009.S01E01.episodename1.mkv
├── E02
│   └── tv.show.2009.S01E02.episodename1.mkv
├── E03
│   └── tv.show.2009.S01E03.episodename1.mkv
├── E04
│   └── tv.show.2009.S01E04.episodename1.mkv
└── E05
    └── tv.show.2009.S01E05.episodename1.mkv

, В то время как Вы упоминаете, что уже создали каталоги эпизода, можно создать их и также переместить файлы в них с модификацией к команде выше. Модификация просто добавляет mkdir "$(echo $file | sed -E 's/.*S[0-9]+(E[0-9]+).*/\1/')" к команде (echo, часть совпадает с в mv прежде). Таким образом команда, чтобы создать каталоги и переместить файлы в них:

for file in *.mkv;do mkdir "$(echo $file | sed -E 's/.*S[0-9]+(E[0-9]+).*/\1/')" && mv "$file" "$(echo $file | sed -E 's/.*S[0-9]+(E[0-9]+).*/\1/')";done

Начальная файловая структура:

.
├── tv.show.2009.S01E01.episodename1.mkv
├── tv.show.2009.S01E02.episodename1.mkv
├── tv.show.2009.S01E03.episodename1.mkv
├── tv.show.2009.S01E04.episodename1.mkv
└── tv.show.2009.S01E05.episodename1.mkv

Результат:

.
├── E01
│   └── tv.show.2009.S01E01.episodename1.mkv
├── E02
│   └── tv.show.2009.S01E02.episodename1.mkv
├── E03
│   └── tv.show.2009.S01E03.episodename1.mkv
├── E04
│   └── tv.show.2009.S01E04.episodename1.mkv
└── E05
    └── tv.show.2009.S01E05.episodename1.mkv
0
ответ дан 7 December 2019 в 18:07

Вот решение, которое я придумал благодаря другим предоставленным ответам

#!/bin/bash

for f in *.mkv *.mp4 *.wmv; do
        if [ -f "$f" ] # does file exist?
        then
                dir=$(echo "$f" | grep -o "E[0-9][0-9]" | head -1) # extract first E## from filename
                if [ "$dir" ] # check if string found
                then
                        mkdir -p "$dir"  # create dir
                        mv "$f" "$dir"     # move file into new dir
                else
                        echo "INCORRECT FILE FORMAT: \""$f"\"" # print error if file format is unexpected
                fi
        fi
done

. Мне пришлось добавить некоторую проверку ошибок, чтобы отловить любые файлы, которые неправильно отформатированы, и для файлов с двумя эпизодами, где имя файла имеет две совпадающие строки E ## (например, tvshow.S01E20E21.mkv ). Для файлов с двумя эпизодами он создаст каталог только для первого номера эпизода и переместит туда файл. Обратите внимание, что этот сценарий также создаст каталоги E ## , поскольку он упрощает использование одного сценария для всего.

2
ответ дан 1 January 2020 в 03:25

Это смотрит на меня как Вы, пытаются просто скопировать весь E01 в папку E01, E02 в папку E02 и т.д. и т.д., если это верно, сценарий удара как это должен работать

#!/bin/bash

cd $(dirname [110])

for orig_filename in ./mkvfiles/*.mkv; do
    dirname="$(dirname $orig_filename)"
    filename=${orig_filename##*/}
    series=${filename%.*}
    episode=${orig_filename}

    [[ $episode =~ [eE][0-9][0-9] ]]
    epi="${BASH_REMATCH[0]}"
    if [ -n "$epi" ]; then
        echo ${epi^^}
        [ ! -d ${epi^^} ] && mkdir -p ${epi^^} || :
        /bin/cp $orig_filename ${epi^^}/$filename
    fi

done

, сценарий просто выполняет итерации всех файлов, фильтрующих для Exx (где xx является числом), и создает/копирует файл к соответствующей папке.

необходимо будет, вероятно, также изменить./mkvfiles / *.mkv

0
ответ дан 7 December 2019 в 18:07

Я думаю, более или менее это может работать на Вас:

#!/bin/bash

for f in *.mkv *.mp4 *.wmv; do # add the extensions you want
  dir=$(echo "$f" | grep -o "S[0-9][0-9]E[0-9][0-9]")
  mkdir -p $dir
  mv $f $dir
done

, Если Вы хотите запустить скрипт только однажды, можно скопировать пути папки к файлу, давайте назовем его list:

/path/to/seriesX
/path/to/seriesY
/path/to/seriesZ

И затем в "корневой" папке сценарий:

#!/bin/bash

mapfile -t array < list
for d in "${array[@]}"; do
  for f in "$d"/*.mkv; do
    dir="$(echo "$f" | grep -o "S[0-9][0-9]E[0-9][0-9]")"
    mkdir -p "$d"/"$dir"
    mv "$f" "$d"/"$dir"/
  done
done
0
ответ дан 7 December 2019 в 18:07

Другие вопросы по тегам:

Похожие вопросы: