LINUX.ORG.RU
ФорумTalks

Перекодировать каталог с музыкой, сохраняя иерархию

 ,


0

2

Правильно ли я понимаю структуру скрипта, которым можно перегнать в другой формат музыкальную коллекцию, сохраняя иерархию?:

1.) Для каждого подкаталога в «Музыка» (и их подкаталогов): создать подкаталог в «Музыка.формат» (find -type d и mkdir -p)

2.) Для каждого файла в «Музыка» и подкаталогах: перегнать из имеющегося формата в нужный, а потом каждый файл нужного формата копирую по его же пути, но с «Музыка» замененным на «Музыка.формат» (find -type f, перекодировщик, cp)

★★

Можно проще - ищешь все музыкальные файлы, собираешь «список» из переменных, каждая из которых - путь к фалу. Скармливаешь этот список кодировщику, а путь куда класть сконвертированные файлы добываешь из этой переменной используя basename и dirname.

alozovskoy ★★★★★ ()

Можно и так, но:

1) Каталоги будут создаваться даже если там нет муз. файлов. Я бы так не делал. Уйти от этого можно если имя каталога вытаскивать из имени файла.

2) От копирования можно уйти, если при конвертации указывать output файл уже в новом каталоге.

P. S. У меня есть такой скрипт, что он делает, думаю, догадаешься:

#!/bin/sh

# This tool will search all *.FLAC files in all subdirectories and convert it to *.MP3

find -name "*.[Ff][Ll][Aa][Cc]" | while read FILE ; do
	OFILE="${FILE:0:(${#FILE}-5)}.mp3"
	echo "Conveting '$FILE' to '$OFILE'"
	flac -dc "$FILE" | lame -v - "$OFILE"
	rm "$FILE"
done

Kroz ★★★★★ ()

Потеряешь всякие куи и обложки, если они есть. Я бы сделал

IFS=$'\n' ; for musfile in `find ./Музыка -name '*.<source_format>'` ; do <перекодирование $musfile> ; done ; unset IFS
Myau ★★★★ ()
Ответ на: комментарий от Kroz

${FILE:0:(${#FILE}-5)}

Ехал баш через перл, сунул баш в перл перл, перл перл перл!

Stahl ★★☆ ()
Ответ на: комментарий от Kroz

Куда уж проще то?

for item in $(find ./ -name "*.mp3"); do megaconverter "$item" $(dirname $item)/$(basename -s mp3 $item).aac; done

(Как-то так, пишу экспромтом).

alozovskoy ★★★★★ ()

Осторожно, башизмы:

while read filename; do
    input="Музыка/$filename"
    output="Музыка.output/${filename%.*}.aac"
    mkdir -p "$(dirname "$output")"
    my_convert --input "$input" --output "$output"
done < <(find Музыка -iname '*.mp3' -printf '%P\n')

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Отлично, мне понравилось. Спасибо. Кстати, ты не мог бы пояснить, почему find в конце (а ещё мне две < непонятны. Вроде, одна нужна?), а не в начале (find ... | while read)? Есть ли принципиальная разница?

Valdor ★★ ()
Последнее исправление: Valdor (всего исправлений: 1)
Ответ на: комментарий от Valdor

А это, собственно, башизм. < <(команда) — «process substitution», пайплайн наоборот. Разница в том, что помещается в сабшелл, а что выполняется в основном процессе.

Ну, точнее, «process substitution» — это <(команда) и эта конструкция раскрывается в имя псевдофайла в /dev, из которого можно читать stdout указанной команды. Соответственно, я из этого псевдофайла перенаправляю стандартный ввод цикла. После подстановки процесса получается что-то вроде

while read filename; do ...; done < /dev/fd/чтототам

Здесь на самом деле пофигу (можно обойтись и обычным пайплайном), но я по привычке всегда пишу так, чтобы при дальнейшей модификации скрипта не словить неочевидный баг, связанный с тем, что в случае обычного пайплайна цикл выполняется в сабшелле и никакие изменения переменных в этом цикле не остаются в силе после его завершения.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.