dr_magnus 15.06.2010 21:42
Скрипты на bash — Перекодирование аудиокниг. Часть 2
В дополнение к первой части дополнил скрипт. Теперь не нужно конкретно указывать директорию, в которой находятся файлы для перекодировки. Достаточно просто указать директорию, в которой лежит коллекция аудиокниг, и скрипт сам определит, что нужно кодировать.Т.к. сам не знаток bash'a, то прошу знатоков ткнуть носом в ошибки и возможности оптимизации скрипта.
UPD: Спасибо lava за mktemp - подправил скрипт немного.
Буду благодарен за отзывы и советы.
NickNill 15.06.2010 22:00 #
+ 0 -
эх, мне еще многому надо научится =) не знал команд basename и dirname. столько sed'ов понаписывал =)))
Кстати, кроме dirname/basename есть прикол следующего вида:
Правда, толково работает, если точно нету слэша в конце =)
Зато как быстро:
??(~)
?hawk? export file=/a/b/c/d
??(~)
?hawk? echo ${file##*/}
d
??(~)
?hawk? echo ${file%/*}
/a/b/c
Правда, толково работает, если точно нету слэша в конце =)
Зато как быстро:
??(~)
?hawk? time for a in `seq 1 10000`; do dirname $file >/dev/null; done
real 0m8.591s
user 0m0.043s
sys 0m1.943s
??(~)
?hawk? time for a in `seq 1 10000`; do echo ${file##*/} >/dev/null; done
real 0m0.303s
user 0m0.267s
sys 0m0.033s
прикольно.. только нифига не понятно.. :-(
это скрипт? как его использовать? можно парочку примеров с комментариями? а можно применительно к моему случаю?
сорри за дилетантство.
??(~)
?hawk? time for a in `seq 1 10000`; do echo ${file##*/} >/dev/null; done
?hawk? time for a in `seq 1 10000`; do echo ${file##*/} >/dev/null; done
это скрипт? как его использовать? можно парочку примеров с комментариями? а можно применительно к моему случаю?
сорри за дилетантство.
time измеряет время выполнения команды
seq выводит последовательность n1 n1+1 n1+2 ... n2
for a in ; do ; done - цикл for, в котором a пройдёт по значениям массива и каждый раз будет выполнена
echo выводит на экран , при этом подставляя специальные переменные
${var} = $var
${var##<маска>} - значение var, но отфильтрованное в соответствии со специфичными правилами.
Таким образом, мы меряем время, в течение которого выполнится цикл для 10000 элементов, который просто выводит отфильтрованное значение переменной в /dev/null - в никуда.
Можно заметить, что в двух приведённых скриптах в одном случае используется команда dirname, а во втором - фильтрация имени. Разница в скорости составила более, чем в 20 раз простая фильтрация быстрее применеия команды dirname.
seq выводит последовательность n1 n1+1 n1+2 ... n2
for a in ; do ; done - цикл for, в котором a пройдёт по значениям массива и каждый раз будет выполнена
echo выводит на экран , при этом подставляя специальные переменные
${var} = $var
${var##<маска>} - значение var, но отфильтрованное в соответствии со специфичными правилами.
Таким образом, мы меряем время, в течение которого выполнится цикл для 10000 элементов, который просто выводит отфильтрованное значение переменной в /dev/null - в никуда.
Можно заметить, что в двух приведённых скриптах в одном случае используется команда dirname, а во втором - фильтрация имени. Разница в скорости составила более, чем в 20 раз простая фильтрация быстрее применеия команды dirname.
спасибо. только боюсь, что для меня это несколько сложновато - слишком давно уже перестал писать, сейчас как будто заново всё учу.
Не рекомендовал бы кидать прямо в /tmp/ - а вдруг коллизии с чем-то другим? =)
Лучше всего - создавать временный директорий со случайным названием. Для этой цели рекомендую man mktemp.
А ещё, возможно, стоит создавать этот самый временный директорий прямо внутри сканируемой папки, имхо. Почему? Ответ прост: тогда команда mv точно будет отрабатывать в пределах одного диска, а при использовании /tmp можно столкнуться с избыточным копированием файлов ;)
Лучше всего - создавать временный директорий со случайным названием. Для этой цели рекомендую man mktemp.
А ещё, возможно, стоит создавать этот самый временный директорий прямо внутри сканируемой папки, имхо. Почему? Ответ прост: тогда команда mv точно будет отрабатывать в пределах одного диска, а при использовании /tmp можно столкнуться с избыточным копированием файлов ;)
ок. спасибо. почитаю.
сам об этом задумывался - диски физически разделены.
сам об этом задумывался - диски физически разделены.
# удаление временной папки
rm "$tmp_dir"
Не отработает. Скажет, что это директорий, а не файл. Надо либо `rmdir`, либо `rm -r`
отлично. добавить нечего. да и коменты сверху просто отличные. сяду наверно пилить свои скрипты для музыки.
Предлагаю:
lame -b 96 --cbr -h --tt "$title" --ta "$artist" --tl "$album" "$input_file" "$tmp_dir/$base_file"
rm "$input_file"
mv "$tmp_dir/$base_file" "$base_dir"
заменить:
lame -b 96 --cbr -h --tt "$title" --ta "$artist" --tl "$album" "$input_file" "$tmp_dir/$base_file" && mv "$tmp_dir/$base_file" "$input_file"
lame -b 96 --cbr -h --tt "$title" --ta "$artist" --tl "$album" "$input_file" "$tmp_dir/$base_file"
rm "$input_file"
mv "$tmp_dir/$base_file" "$base_dir"
заменить:
lame -b 96 --cbr -h --tt "$title" --ta "$artist" --tl "$album" "$input_file" "$tmp_dir/$base_file" && mv "$tmp_dir/$base_file" "$input_file"
&& mv "$tmp_dir/$base_file" "$input_file"
а это перезапишет исходный файл без подтверждения?
это будет работать только, если lame справится с кодированием. && хорошая вещь.
Я пока остановился на таком варианте ( осталось только секция для пропуска
битрейта если он меньше необходимого )
битрейта если он меньше необходимого )
#!/bin/sh
dir_name="${1}"
cd "${dir_name}"
#требуемый битрейт
bit=64
if < ! -d $bit > ; then
mkdir $bit
fi
#поиск( по символьным ссылкам тоже )
find -L -iname '*.mp3' | while read input_file;
do
TITLE=$(mid3v2 -l "$input_file" | sed -n 's/^TIT2=//p')
ARTIST=$(mid3v2 -l "$input_file" | sed -n 's/^TPE1=//p')
ALBUM=$(mid3v2 -l "$input_file" | sed -n 's/^TALB=//p')
# куда будет сохранять пережатый файл
output_file="./$bit/$input_file"
# создаем вложенные папки при необходимости
if < ! -d "$(dirname "$output_file")" > ; then mkdir -p "$(dirname "$output_file")"
fi
lame -b $bit --cbr --tt "$TITLE" --ta "$ARTIST" --tl "$ALBUM" "$input_file" "$output_file";
done
я считаю скрипт в шапке не подходит для людей которые колекционируют аудиокниги в хороших битрейтах , так как он тупо заменяет!!! их на файлы с низким битрейтом .
Мой скрипт работает по другому принципу
1) выбираем из книжек те , которые хотим закинуть в плейер или еще куда , не меняя основную коллекцию .
2) Кидаем в любую папку симовльные ссылки на папки с отобранными книгами
3) Кормим эту папку скрипту
4) Получаем в ней поддиректорию именованную выбранным в нем битрейтом , внутри которой наши пожатые книжки с исходной структурой каталогов.
В итоге исходные книги не пострадали ))) , но обзовелись более худыми копиями
Мой скрипт работает по другому принципу
1) выбираем из книжек те , которые хотим закинуть в плейер или еще куда , не меняя основную коллекцию .
2) Кидаем в любую папку симовльные ссылки на папки с отобранными книгами
3) Кормим эту папку скрипту
4) Получаем в ней поддиректорию именованную выбранным в нем битрейтом , внутри которой наши пожатые книжки с исходной структурой каталогов.
В итоге исходные книги не пострадали ))) , но обзовелись более худыми копиями