Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: BASH - Авоматизация кодирования директорий  (Прочитано 2058 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн arch!ver

  • Автор темы
  • Старожил
  • *
  • Сообщений: 1260
    • Просмотр профиля
Началось всё с попытки перевести CD диск во flac с предварительным апсемплом, для плейера...

Заход первый:
Перетаскивание файлов диска в директорию /home/user/music - но тут сразу же случилось одно но - файлы с пробелами Track 1.wav и bash отказывается их понимать, а заключение директории в казычки ничего не дало... Родилась идея о массовом переименовании файлов... Гуглил, шнырял, матерился, нашёл:
Скрипт
cd /home/user/music
rename 's/ /_/g' *

Заход второй:
Возникла необходимость в массовой перекодировке файлов дериктории согасно основному заданию, благо скрипт на эту тему есть и принцип несколько ясен, несмотря на сопустствующие туманности в виду очень плохого знакомства с принципами bash как такового...
Скрипт
for a in /home/user/music/*.wav ;
do

ffmpeg -i "$a" -c:a pcm_s32le -ar 192000 -vol 256 $a.wav

done
На выходе получаются файлы с прикольным двойным расширением :), типа - Track_1.wav.wav - ну да и ладно бы с ним...

Заход третий:
Последующая конвертация во flac
Скрипт
for b in /home/user/music/*.wav.wav ;
do
 
ffmpeg -i "$b" -c:a flac -f flac $b.flac
 
done
На выходе получается ещё больший прикол с наименованием и расширением Track_1.wav.wav.flac - ну в принципе тоже не беда, но наводит на последующую мысль о следующем массовом переименовании...

Заход четвёртый:
Таки массовое переименование, заключительное...
Скрипт
cd /home/user/music/
rename 's/.wav.wav.flac/.flac/g' *


Всязи со всем этим "научным онанизмом", отнявшим у меня не менее суток и подарившим одну бессонную ночь, у меня возникло два глобальных вопроса...
Вопрос первый и важный:
1. Как автоматизировать работу всех этих скриптов, объеденив их в один... Ибо как показала практика, моих знаний на этот счёт оказалось крайне недостаточно ввиду того же очень слабого знакомства с bash  его понимания... Для меня пока это очень тёмный лес...
Вопрос второй, тоже не менее важный для меня, но вторичный, направленный на прояснения понимания сути вещей:
2. Что означаю пробелы в скрипте fo a in после do и перед done - ибо без них вся эта "научная шняга" нифига не работает несмотря на то, что в сети примеры приводятся без каких либо пробелов  :)
Пример:
for a in /home/user/music/*.wav ;
do
--- ??? ---
ffmpeg -i "$a" -c:a pcm_s32le -ar 192000 -vol 256 $a.wav
--- ??? ---
done
« Последнее редактирование: 29 Июля 2014, 20:11:57 от archiver »

Оффлайн SvMidi

  • Активист
  • *
  • Сообщений: 815
    • Просмотр профиля
Код: (bash) [Выделить]
#!/bin/bash
for a in $HOME/Music/*.wav ;
do
   ffmpeg -i "$a" -c:a pcm_s32le -ar 192000 -vol 256 "$a"
   ffmpeg -i "$a" -c:a flac -f flac "${a%.*}.flac"
done
rm $HOME/Music/*.wav
« Последнее редактирование: 29 Июля 2014, 20:45:51 от SvMidi »
Я знаю только то, что ничего не знаю, остальные не знают и этого.

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
файлы с пробелами Track 1.wav и bash отказывается их понимать, а заключение директории в казычки ничего не дало...
Вполне вероятно, что решаемо без переименования.
Надо только внимательно следить за экранированием спецсимволов (пробелов в частности) при работе с переменными и при чтении имён файлов в цикле.

На выходе получаются файлы с прикольным двойным расширением :), типа - Track_1.wav.wav
Обычно имя читается в переменную, а потом отбрасывается исходное расширение через
Код: (bash) [Выделить]
"${FILE%.*}"
Как автоматизировать работу всех этих скриптов, объеденив их в один...
Один из наиболее гибких сценариев реализации рекурсивной обработки:
Код: (bash) [Выделить]
find /dir -type "f" -iname "*.ext" | while read FILE
do
    echo "$FILE" # тут обычно блок команд по обработке файла
done

Что означаю пробелы в скрипте fo a in после do и перед done - ибо без них вся эта "научная шняга" нифига не работает несмотря на то, что в сети примеры приводятся без каких либо пробелов
Должно работать без пробелов.
Как вариант, у вас там концы строк в формате DOS или ещё какие-нибудь невидимые символы.
« Последнее редактирование: 29 Июля 2014, 20:55:00 от ArcFi »

Оффлайн arch!ver

  • Автор темы
  • Старожил
  • *
  • Сообщений: 1260
    • Просмотр профиля
SvMidi,
Сценарий не работает должным образом - требует ручного подтверждения перезаписи каждого файла...

Пользователь решил продолжить мысль [time]29 Июль 2014, 23:38:08[/time]:
файлы с пробелами Track 1.wav и bash отказывается их понимать, а заключение директории в казычки ничего не дало...
Вполне вероятно, что решаемо без переименования.
Надо только внимательно следить за экранированием спецсимволов (пробелов в частности) при работе с переменными и при чтении имён файлов в цикле.

Не решаемо на данном этапе, - экранирование строки
for a in "/home/user/music/*.wav" ;приводит к неработоспособности скрипта, ибо экраниование в этом контесте рассматрирается скриптом как "единая система", а не набор треков...
А экранирование подобным образом
for a in /home/user/music/"*.wav" ;тоже ничего не даёт... возникает вопрос, - а bash он вообще когда нибудь прямым бывает? - или его вот так каждый раз приходится выпрямлять за счёт сторонних рук творческих программистов и трепыханий вольных ковыряльщиков? :)


Пользователь решил продолжить мысль [time]29 Июль 2014, 23:44:28[/time]:
Один из наиболее гибких сценариев реализации рекурсивной обработки:
Код: (bash) [Выделить]
find /dir -type "f" -iname "*.ext" | while read FILE
do
    echo "$FILE" # тут обычно блок команд по обработке файла
done

find /home/music/M/ -type "f" -iname "*.wav" | while read FILE
do
"$FILE" ffmpeg -i "$f" -c:a pcm_s32le -ar 192000 -vol 256 "$f"
"$FILE" ffmpeg -i "$f" -c:a flac -f flac "${f%.*}.flac"
done
Вообще не пашет - выводит список строк на экран с загадочным сообщением
bash: /home/user/music/Track_2.wav: Отказано в доступе
, - или вообще какую то белиберду из ошмётков содержимого соседних папок :D... Скорее всего я просто напроч не догнал сам принцим, если можно - то не помешало бы с примерами и толкованиями нюансов, включая заковыристые мелочи, которые на первый взгляд могут обманчиво показаться несущественными...

Пользователь решил продолжить мысль [time]29 Июль 2014, 23:49:01[/time]:
Должно работать без пробелов.
Как вариант, у вас там концы строк в формате DOS или ещё какие-нибудь невидимые символы.
Да, разобрался - пересохранил leafpad с опцией CR...
« Последнее редактирование: 29 Июля 2014, 23:58:42 от archiver »

Оффлайн SvMidi

  • Активист
  • *
  • Сообщений: 815
    • Просмотр профиля
Я так понимаю просит подтверждение ffmpeg, тогда просто с другим именем сделать:
Код: (bash) [Выделить]
#!/bin/bash
for a in $HOME/Music/*.wav ;
do
   name=${a%.*}
   ffmpeg -i "$a" -c:a pcm_s32le -ar 192000 -vol 256 "$name"_tmp.wav
   ffmpeg -i "$name"_tmp.wav -c:a flac -f flac "$name.flac"
done
rm -f $HOME/Music/*.wav
« Последнее редактирование: 30 Июля 2014, 10:45:32 от SvMidi »
Я знаю только то, что ничего не знаю, остальные не знают и этого.

Krjd

  • Гость
SvMidi,
Цитировать
Я так понимаю просит подтверждение ffmpeg
Цитировать
-y (global)
           Overwrite output files without asking.

Пользователь решил продолжить мысль [time]30 Июль 2014, 11:03:36[/time]:
Не решаемо на данном этапе, - экранирование строки
for a in "/home/user/music/*.wav" ;приводит к неработоспособности скрипта, ибо экраниование в этом контесте рассматрирается скриптом как "единая система", а не набор треков...
А экранирование подобным образом
for a in /home/user/music/"*.wav" ;тоже ничего не даёт... возникает вопрос, - а bash он вообще когда нибудь прямым бывает? - или его вот так каждый раз приходится выпрямлять за счёт сторонних рук творческих программистов и трепыханий вольных ковыряльщиков? :)
$ ls /home/sergey/tmp/
10 1.wav  12 1.wav  15 1.wav  18 1.wav  2 1.wav  5 1.wav  8 1.wav
11 1.wav  13 1.wav  16 1.wav  19 1.wav  3 1.wav  6 1.wav  9 1.wav
1 1.wav   14 1.wav  17 1.wav  20 1.wav  4 1.wav  7 1.wav

$ for a in /home/sergey/tmp/*.wav; do echo "$a"; done
/home/sergey/tmp/10 1.wav
/home/sergey/tmp/11 1.wav
/home/sergey/tmp/1 1.wav
/home/sergey/tmp/12 1.wav
/home/sergey/tmp/13 1.wav
/home/sergey/tmp/14 1.wav
/home/sergey/tmp/15 1.wav
/home/sergey/tmp/16 1.wav
/home/sergey/tmp/17 1.wav
/home/sergey/tmp/18 1.wav
/home/sergey/tmp/19 1.wav
/home/sergey/tmp/20 1.wav
/home/sergey/tmp/2 1.wav
/home/sergey/tmp/3 1.wav
/home/sergey/tmp/4 1.wav
/home/sergey/tmp/5 1.wav
/home/sergey/tmp/6 1.wav
/home/sergey/tmp/7 1.wav
/home/sergey/tmp/8 1.wav
/home/sergey/tmp/9 1.wav
или я чего-то не понял?
« Последнее редактирование: 30 Июля 2014, 11:04:33 от D101101 »

Оффлайн arch!ver

  • Автор темы
  • Старожил
  • *
  • Сообщений: 1260
    • Просмотр профиля
< -y > Overwrite output files without asking.
Точно, точно, точно - совсем из головы вылетела эта опция, - попробую...

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
тоже ничего не даёт... возникает вопрос, - а bash он вообще когда нибудь прямым бывает?
С башем всё OK, а вот "man ffmpeg" нужно читать внимательнее:
Код: (bash) [Выделить]
find dir/ -type "f" -iname "*.wav" | while read FILE
do
    ffmpeg -nostdin -y -i "$FILE" -c:a pcm_s32le -ar 192000 -vol 256 "$FILE"
    ffmpeg -nostdin -i "$FILE" -c:a flac -f flac "${FILE%.*}.flac"
done

Оффлайн arch!ver

  • Автор темы
  • Старожил
  • *
  • Сообщений: 1260
    • Просмотр профиля
С башем всё OK, а вот "man ffmpeg" нужно читать внимательнее:
Скорее вопрос здесь не столько в мане от ффмпег, сколько в корректности примеров :) ... Сам ффмпег не вызывает особых проблем, ибо завязван на одной командной базе, а вот в совокупности с башем - может вызвать реальные непонятки и даже грубые ошибки - это ВАЖНЫЙ нюанс ;)
У меня вообще всё очень плохо - относительно переменных и самого принципа программирования... Не догоняю я эту тему, а если и догоняю. то очень плохо...
Спасибо, попробую... Если будет лажа и непонятки - отпишусь по теме...
« Последнее редактирование: 30 Июля 2014, 13:50:45 от archiver »

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
На всякий случай, ещё раз подчеркну, что в контексте пакетной обработки для исключения проблем с именами файлов, ffmpeg следует использовать с опцией "-nostdin".

Оффлайн arch!ver

  • Автор темы
  • Старожил
  • *
  • Сообщений: 1260
    • Просмотр профиля
На всякий случай, ещё раз подчеркну, что в контексте пакетной обработки для исключения проблем с чтением имён файлов ffmpeg следует использовать с опцией "-nostdin".
Ок - отвентилирую этот нюанс...

Оффлайн start733

  • Участник
  • *
  • Сообщений: 248
    • Просмотр профиля
Re: BASH - Авоматизация кодирования директорий
« Ответ #11 : 02 Августа 2014, 19:02:42 »
меня часто выручал этот скрипт:
#!/bin/bash
# Перекодирует рекурсивно в текущем каталоге имена
# файлов и каталогов в транслит.
shopt -s nullglob
for NAME in * ; do
TRS=`echo $NAME | sed "y/абвгдезийклмнопрстуфхцы /abvgdezijklmnoprstufxcy_/"`
TRS=`echo $TRS | sed "y/АБВГДЕЗИЙКЛМНОПРСТУФХЦЫ/ABVGDEZIJKLMNOPRSTUFXCY/"`
TRS=${TRS//ч/ch};
TRS=${TRS//Ч/CH} TRS=${TRS//ш/sh};
TRS=${TRS//Ш/SH} TRS=${TRS//ё/jo};
TRS=${TRS//Ё/JO} TRS=${TRS//ж/zh};
TRS=${TRS//Ж/ZH} TRS=${TRS//щ/sh\'};
TRS=${TRS///SH\'} TRS=${TRS//э/je};
TRS=${TRS//Э/JE} TRS=${TRS//ю/ju};
TRS=${TRS//Ю/JU} TRS=${TRS//я/ja};
TRS=${TRS//Я/JA} TRS=${TRS//ъ/\`};
TRS=${TRS//Щ/SH};
TRS=${TRS//Ъ/\`};
TRS=${TRS//Ь/\`};
TRS=${TRS//\`} TRS=${TRS//ь/\'};
TRS=${TRS//\'}
if [[ `file -b "$NAME"` == directory ]]; then
mv -v "$NAME" "$TRS"
cd "$TRS"
"../$0"
cd ..
else
mv -v "$NAME" "$TRS"
fi
done


Источник http://mintlinux.ru/forum/thread1031.html

Кроме того заменяет пробелы на подчеркивание.
« Последнее редактирование: 02 Августа 2014, 19:06:27 от start733 »

Оффлайн arch!ver

  • Автор темы
  • Старожил
  • *
  • Сообщений: 1260
    • Просмотр профиля
Re: BASH - Авоматизация кодирования директорий
« Ответ #12 : 04 Ноября 2014, 17:17:44 »
Я так понимаю просит подтверждение ffmpeg, тогда просто с другим именем сделать:
Код: (bash) [Выделить]
#!/bin/bash
for a in $HOME/Music/*.wav ;
do
   name=${a%.*}
   ffmpeg -i "$a" -c:a pcm_s32le -ar 192000 -vol 256 "$name"_tmp.wav
   ffmpeg -i "$name"_tmp.wav -c:a flac -f flac "$name.flac"
done
rm -f $HOME/Music/*.wav

Оптимальным оказался именно этот вариант... Скрипт в котором ведётся перезапись файлов поверху, привёл к искажению звучания треков...
Сделал несколько по своему:
for a in /comp/user/music/*.wav ;
do
name=${a%.*}
ffmpeg -i "$a" -c:a pcm_s24le -ar 192000 -vol 256 "$name"_tmp.wav ;
ffmpeg -i "$name"_tmp.wav -c:a flac -f flac "$name.flac"
done
Всё прошло успешно - результат улыбает качеством...

 

Страница сгенерирована за 0.022 секунд. Запросов: 22.