Цикл FOR по списку в bash работает хорошо. До тех пор, пока внутри элементов списка не появляются пробелы - вместе с пробелами появляются и проблемы: каждое слово в составе элемента списка рассматривается отдельно, и если попадается файл вроде "цикл не работает", то for будет выполнен для него три раза - для "цикл", для "не" и для "работает", что не есть хорошо.
Понадобилось мне сконвертировать несколько файлов из png в jpg. И как раз наступил на упомянутые грабли (имена файлов настоящие и опечатки в слове "внутренний" нет):
$ for a in `ls -Q litb\ внтуренний\ счет*.png`; do echo "$a"; done
"litb
внтуренний
счет2.png"
"litb
внтуренний
счет.png"
Понадобилось мне сконвертировать несколько файлов из png в jpg. И как раз наступил на упомянутые грабли (имена файлов настоящие и опечатки в слове "внутренний" нет):
$ for a in `ls -Q litb\ внтуренний\ счет*.png`; do echo "$a"; done
"litb
внтуренний
счет2.png"
"litb
внтуренний
счет.png"
Разумеется, convert обиделся и сказал, что не знает, что я от него хочу, получив на входе такую абракадабру.
Несколько различных способов решения я нашел здесь. Выбрал простейший: изменить значение переменной IFS, отвечающей за разделитель слов. По умолчанию IFS=" " (пробел), что совершенно не подходит для моей задачи. Поэтому родилась такая уродливая команда. Уродливая она, правда, для короткого цикла - для обработки двух файлов быстрее получилось бы два раза запустить convert, подсунув ему нужные имена. Но в случае обработки большого списка файлов она очень даже уместна.
$ oldifs="$IFS"; IFS=$(echo -en "\n\b"); for a in $(ls litb\ внтуренний\ счет*.png); do nam=$(basename -s png "$a")jpg; convert "$a" "$nam"; done; IFS="$oldifs"
Теперь подробнее.
- сохраняем старое значение IFS
- присваиваем IFS новое значение
- цикл по результатам команды ls
- чтобы не возиться с кавычками, новое имя файла формируем в переменной nam
- возвращаем исходное значение IFS
Немного о команде basename. С ключом -s она отсекает от имени файла указанное расширение, суффикс, в данном случае - "png"
Комментариев нет:
Отправить комментарий
Пожалуйста, воздержитесь от грубостей и персональных нападок.
Я не против матерщины, но она должна быть уместной и использоваться для выражения эмоций, а не в качестве основного средства выражения мыслей.