Как сделать сценарий оболочки для перемещения файлов в отдельные папки на основе имени файла?
Я хочу автоматизировать перемещение файлов эпизодов телешоу в отдельные каталоги для каждого эпизода.
По сути, в папке, в которой я хочу запустить скрипт, у меня есть список файлов. Например: tvshow.2009.S01E01.episodename1.mkv
,tvshow.2009.S01E02.episodename2.mkv
, tvshow.2009.S01E03.episodename3.mkv
и т. д. и пустые каталоги в формате E01
, E02
, E03
и т. д.
На этом этапе я перемещал файлы вручную с помощью автозаполнения вкладки в командной строке. По сути, я печатаю:
mv t
а затемнажмите клавишу Tab, чтобы автоматически завершить
mv tv.show.2009.S01E0
затем введите 1
и снова нажмите Tab, чтобы добраться до
mv tv.show.2009.S01E01.episodename1.mkv
затем я набираю правильную папку, чтобы добраться до
mv tv.show.2009.S01E01.episodename1.mkv E01/
и затем нажмите Enter, чтобы завершить команду. Я должен повторить шаги для такого же количества эпизодов, что и в исходном каталоге, и, учитывая тот факт, что я, по сути, повторяю те же самые шаги и просто повторяю номер эпизода, это кажется идеальным использованием цикла for в сценарии.
Проблема заключается в том, что файлы не всегда имеют один и тот же формат и, очевидно, будут иметь разные имена в зависимости от шоу. Что постоянно, хотя это S##E##
всегда будет отображаться в имени файла, и мне нужно только использовать E##
определить правильный файл и переместить его в папку, которая уже существует и точно соответствует E##
из файла.
Я опытный программист, но еще не работал со скриптами оболочки. Моя мысль состоит в том, чтобы, возможно, перебрать все существующие E##
папки, найдите файл, который содержит это E##
последовательность, а затем переместите этот файл в папку. К сожалению, я не уверен, правильно ли делать это с помощью скрипта, который я могу запустить из командной строки.
Будет ли кто-нибудь иметь предложенный план подхода или сможет указать мне на ресурс, к которому я мог бы обратиться за помощью?
3 ответа
Вы можете использовать это из каталога, где у вас есть файлы и пустые каталоги, предполагая, что ваши файлы имеют .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
в конце sed
команда).
Исходная структура файла:
.
├── 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
Вот решение, которое я придумал благодаря другим предоставленным ответам
#!/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##
каталоги, так как это упрощает использование одного сценария для всего.
Я думаю, более или менее это может работать для вас:
#!/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
Мне кажется, что вы пытаетесь просто скопировать все E01 в папку E01, E02 в папку E02 и т. Д. И т. Д., Если это так, сценарий bash, как это должно работать
#!/bin/bash
cd $(dirname $0)
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