LINUX.ORG.RU

[bash] кривой скрипт

 


0

1

Пытаюсь написать скрипт, который ищет mp3 файлы и перекодирует их в ogg. Вроде все работает, но часто ffmpeg выдает ошибку, что не может найти файл с таким именем. В качестве имени говорит кусок настоящего имени файла. Как такое может быть, если ему имена файлов передаются целиком? Сам скрипт?

#! /bin/sh

find -iname "*.mp3" | while read -r i; do ffmpeg -v info -i "$i" -acodec libvorbis "$i.ogg" && rm "$i"; done
★★★★★

Наверно лучше будет посмотреть на ошибку и имя оригинального файла.

Так же можете попробовать добавить ковычек.

kostik87 ★★★★★
()

Пытаюсь написать скрипт, который ищет mp3 файлы и перекодирует их в ogg.

Зачем? В размере экономии большой не будет. В качестве заведомо потеряешь.
Если задача просто написать скрипт, то поиск по сайту даст много обходов проблемы пробелов в имени файла.

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

В размере экономия есть, я проверил. Качество не изменилось (в всяком случае на мой слух). Пробелы обходятся, проблема где-то в другом месте.

vurdalak ★★★★★
() автор топика

выхлоп

$ bash -x scriptname.sh

на нескольких файлах покажи, включая «неправильные» файлы.

uspen ★★★★★
()
Ответ на: комментарий от imul

Неправильный файл:

./Город 312/Вне зоны доступа (2006)/06 - Поговори со Мной.mp3

(понимается как «со Мной.mp3»)

Правильный файл:

./Город 312/Вне зоны доступа (2006)/08 - Береги Себя.mp3

Не вижу коренных различий.

vurdalak ★★★★★
() автор топика
Ответ на: комментарий от uspen

Как ограничить вывод ffmpeg до 1 строки на файл? По умолчанию там огромная простыня, я даже не успеваю отслеживать, какие файлы прошли, а какие нет.

vurdalak ★★★★★
() автор топика

./Complex numbers/Last ring MAXI-SINGLE (2001 - 2009)/04 - COMPLEX NUMBERS - KA-52 Alligator.mp3

превращается в

BERS - KA-52 Alligator.mp3

echo в цикле подтверждает. Значит, он где-то неправильно либо выводит из find, либо читает read'ом.

vurdalak ★★★★★
() автор топика
Ответ на: комментарий от vurdalak

06 - Поговори со Мной.mp3

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

imul ★★★★★
()
Ответ на: комментарий от silw

Хм, я о нем забыл. Так будет даже проще :)

vurdalak ★★★★★
() автор топика
Ответ на: комментарий от aol

find: отсутствует аргумент у `-exec'

vurdalak ★★★★★
() автор топика

find не нужен, рекурсивный глоббинг - наш юзерфрендли друг

zolden ★★★★★
()
Ответ на: комментарий от aol

find -iname «*.mp3» -exec ffmpeg -v info -i «{}» -acodec libvorbis «{}.ogg» && rm «{}» \;

find -iname «*.mp3» -exec echo «{}» && ffmpeg -v info -i «{}» -acodec libvorbis «{}.ogg» && rm «{}» \;

Очень хочется посмотреть на то имя, на котором скрипт раньше спотыкался. :D

imul ★★★★★
()
Ответ на: комментарий от vurdalak

ммм... действительно..
вобщем, можно всю эту штуку засунуть в скрипт, а его уже вызывать из exec
но это уже почти тоже самое, что и в ОП..

aol ★★★★★
()

++man_xargs

anonymous
()
Ответ на: комментарий от anonymous

Да, я понял уже. Спасибо. Писал когда просто вставил в ту команду эхо и бездумно нажал отправить.

imul ★★★★★
()

Еще вопрос: можно ли сделать так, чтобы по CTRL-C завершался весь скрипт, а не текущий его процесс?

vurdalak ★★★★★
() автор топика

$IFS по умолчанию содержит пробел, поэтому read считывает куски имён файлов. Если бы в цикле был бы более сложный код, я бы сделал так:

find -iname "*.mp3" -print0 | while read -d $'\x00' -r i; do
        ffmpeg -v info -i "$i" -acodec libvorbis "$i.ogg" && rm "$i"
done

Но тут можно попробовать и xargs, хотя менее наглядно.

gentoo_root ★★★★★
()

Велик мой.

#!/bin/bash

fEXT='.*\.\(mp3\|wma\|wav\|cue\|flac\)$'
sfEXT=`echo "$fEXT"| sed -e 's/\(\.\*\\\.\)//'`
tEXT='ogg'
#TYPE='mp3'
NPT=8
NPTC=1
SPATH='./'

if [ -n "$1" ]
then
    SPATH="$1"
fi


#ls -1 *.$EXT|while read FNAME; do

find "$SPATH" -type f -iregex "$fEXT" -not -ipath "./*$tEXT/*" |while read FNAME; do

	nFNAME=`echo "$FNAME"|sed -e "s/$sfEXT/$tEXT/I" -e 's/.\///'`
    #IX=`expr index "$FNAME" "."`
    #if [ "$IX" eq 0 ]
    #then
    #    TYPE=""
    #else
    #    TYPE=${FNAME#*.}
    #fi

    nfDIR=`dirname "$nFNAME"`
    
   
    if [ "$nfDIR" = "." ];then
        nfDIR=""
    fi
    
	mkdir -p "$tEXT/$nfDIR"

	echo "$FNAME" " -> " "$tEXT/$nFNAME"

	if [ "$NPTC" -lt "$NPT" ];then
		NPTC=$(($NPTC + 1))
		#sox "$FNAME" "$tEXT/$nFNAME" &
		ffmpeg -i "$FNAME" -acodec libvorbis -ab 192000 "$tEXT/$nFNAME" </dev/null &
	else
		NPTC=1
		#sox "$FNAME" "$tEXT/$nFNAME"
		ffmpeg -i "$FNAME" -acodec libvorbis -ab 192000 "$tEXT/$nFNAME" </dev/null
	fi
	
	#sox "$FNAME" "$tEXT/$nFNAME"
	#ffmpeg -i "$FNAME" -acodec vorbis -ab 192000 "$tEXT/$nFNAME" </dev/null
		
	echo "-[> NEXT <]------------------"
	
done;


pEXT='.*\.\(jpg\|jpeg\|png\|bmp\|avi\|mpg\|wmv\|flv\|mkv\)$'

find $1 -type f -iregex "$pEXT" -not -ipath "./*$tEXT/*"|while read FNAME; do

	nFNAME=`echo "$FNAME"|sed -e 's/.\///'`

    nfDIR=`dirname "$nFNAME"`

    if [ "$nfDIR" = "." ];then
        nfDIR=""
    fi
    
    mkdir -p "$tEXT/$nfDIR"

	echo "$FNAME" " -> " "$tEXT/$nfDIR/"

	cp "$FNAME" "$tEXT/$nfDIR/" &
		
	echo "-[> NEXT <]------------------"

done;
Bad_ptr ★★★★★
()
Ответ на: комментарий от vurdalak

Запусти с рутовыми правами — узнаешь :)))
А так вообще есть например директория mp3, Запускаем скрипт в этой директории и он создаст внутри директорию ogg с копией структуры директории mp3, только файлы будут в формате огг и также скопернёт туда и обложки/клипы. Вот, както так.

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

Короче велик. Был написан очень давно, только начинал разбираться со всеми этими башскриптами.

Bad_ptr ★★★★★
()

Поддерживаю gentoo_root, нужно использовать \0 в качестве разделителя (нулевой байт и «/» - символы, которых не бывает в именах файлов) и оборачивать в кавычки всё, что может содержать пробелы и ненужные аргументы командной строки:

find -iname "*.mp3" -print0 | while read -d $'\0' -r i; do ffmpeg -v info -i "$i" -acodec libvorbis "${i%.mp3}.ogg" && rm "$i"; done
AITap ★★★★★
()

Если нужны теги, то добавил бы -map_metadata 0:g:0 для последних версий ffmpeg или -map_metadata 0:0 для более старых.

anonymous
()

pacpl --recursive --preserve --only mp3 -t ogg --oggqual 5 --outdir ~/Music/oggs ~/Music

Теги скопируются, структура каталогов тоже скопируется (можно не копировать структуру, убрав ключ --preserve).
А зачем кодировать lossy в lossy?

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

А зачем кодировать lossy в lossy?

Качество не меняется (на слух), а ворбис занимает меньше места.

vurdalak ★★★★★
() автор топика
Ответ на: комментарий от vurdalak

В смысле «нужны теги»? Они и так сохранились.

О, прогресс не стоит на месте!

anonymous
()

mp3 файлы и перекодирует их в ogg

ак47 - говно.мр3
бутырка - дерьмо.ogg

anonymous
()
Ответ на: комментарий от vurdalak

Качество не меняется (на слух)

ну 300гц-8000гц дальше ужать проблематично, да.

anonymous
()
Ответ на: комментарий от Deleted

Чтобы выполнить несколько команд. Если скармливать всю цепочку команд xargs'у, придётся использовать конструкцию вида xargs -0 sh -c "...", и вся прелесть экранирования от нежелательных символов исчезнет. Можно будет создать файл с именем из нескольких кавычек, и выполнение команды прервётся из-за синтаксической ошибки.

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

В принципе, можно и без цикла всё переконвертировать. Но тогда не получится красиво избавиться от двойного расширения и сразу удалить исходник.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.