bash-циклы по параметрам, и имена файлов с пробелами

На самом деле это единственный раздел про unix на этом форуме

Модератор: /dev/random

Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

bash-циклы по параметрам, и имена файлов с пробелами

Сообщение rm_ » 14.02.2009 03:41

Допустим, есть каталог с двумя файлами, названными:

Код: Выделить всё

file one.txt
file two.txt

Есть шелл-скрипт:

Код: Выделить всё

for file in $*
do
  echo "Processing $file..."
done

При выполнении в этом каталоге с параметром *.txt (который шеллом экспандится в оба имени файла), он выдаёт:

Код: Выделить всё

$ ./test.sh *.txt
Processing file...
Processing one.txt...
Processing file...
Processing two.txt...

Как сделать, чтобы пробелы в именах файлов не приводили к такому результату? :)
Спасибо сказали:

Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение Portnov » 14.02.2009 07:39

Ничо умнее чем запускать скрипт
./script "*.txt"
(с кавычками) не предложу.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:

Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение RasenHerz » 14.02.2009 09:14

тоже недавно столкнулся с такой проблемой когда с помощью mp32ogg конвертировал очередную часть своей музыкальной коллекции, так что некоторые некоторые каталоги пришлось перегонять ручками.
присоединяюсь с вопросом к автору.
Спасибо сказали:

Аватара пользователя
korisk
Сообщения: 205
ОС: Xubuntu

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение korisk » 14.02.2009 09:28

Можно попробовать пошаманить с xargs

find . -type f -print0|xargs -null cat
Распечатает содержимое всех файлов текущего каталога.

Удач
Registerd Linux user #486684 at http://counter.li.org/
Спасибо сказали:

Аватара пользователя
Voice
Сообщения: 1073
Статус: столлманист
ОС: Debian GNU/Linux

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение Voice » 14.02.2009 13:11

Можно так:

find -name '*.mp3' -print | while read line; do echo $line; done;
"И может собственных Платонов и быстрых разумом Невтонов российская земля рождать."
М. В. Ломоносов
Спасибо сказали:

Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение rm_ » 14.02.2009 13:29

Ничо умнее чем запускать скрипт
./script "*.txt"
(с кавычками) не предложу.

Задача в том, чтобы скрипт выполненный как ./script *.txt отрабатывал нормально. Все программы так умеют, не требуя ничего заключать в кавычки.

В общем похоже я на PHP буду этот скрипт делать, и дальше убеждаясь, что мало-мальски нетривиальные скрипты на шелле лучше даже и не начинать.

Код: Выделить всё

#!/usr/bin/php
<?php
  array_shift($argv);
  foreach($argv as $arg) {
    echo("Processing $arg...\n");
  }
?>

Работает:

Код: Выделить всё

$ ./test.php *.txt
Processing file one.txt...
Processing file two.txt...

Спасибо всем за помощь. :)
Спасибо сказали:

Аватара пользователя
diesel
Модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение diesel » 14.02.2009 14:21

rm_ писал(а):
14.02.2009 13:29
Задача в том, чтобы скрипт выполненный как ./script *.txt отрабатывал нормально. Все программы так умеют, не требуя ничего заключать в кавычки.


Код: Выделить всё

diesel@debian:/tmp/testdir$ ./tmp.sh *.txt
-rw-r--r-- 1 diesel diesel 0 2009-02-14 13:18 file with spaces.txt
-rw-r--r-- 1 diesel diesel 0 2009-02-14 13:18 file_with_no_spaces.txt
diesel@debian:/tmp/testdir$ ls -l
total 4
-rw-r--r-- 1 diesel diesel  0 2009-02-14 13:18 file_with_no_spaces.txt
-rw-r--r-- 1 diesel diesel  0 2009-02-14 13:18 file with spaces.txt
-rwxr-xr-x 1 diesel diesel 77 2009-02-14 13:19 tmp.sh
diesel@debian:/tmp/testdir$ cat tmp.sh
#!/bin/bash

for i in `seq 0 $(($#-1))`; do
    ls -l "${BASH_ARGV[$i]}";
done

Например вот так, если речь идет о bash. Хотя постановка задачи мне кажется не очень правильной, по крайней мере непривычна - точно. Для того чтобы доказывать рульность php в качестве штуки для скриптования прийдется выбрать другой пример (:
Спасибо сказали:

watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение watashiwa_daredeska » 14.02.2009 14:37

Код: Выделить всё

for f in "$@"; do
    echo "$f"
done



diesel писал(а):
14.02.2009 14:21
Хотя постановка задачи мне кажется не очень правильной, по крайней мере непривычна - точно.
Нормальная постановка. Есть множествно программ, которые принимают произвольное число аргументов и выполняют над ними определенное действие. Для таких программ, в частности, и придуман xargs.
Спасибо сказали:

Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение rm_ » 14.02.2009 14:38

diesel писал(а):
14.02.2009 14:21
Для того чтобы доказывать рульность php в качестве штуки для скриптования прийдется выбрать другой пример (:

Да не в PHP дело... Ошибаетесь, если думаете что топик за этим был создан.

Я делал скрипт по преобразованию архива любого типа (из поддерживаемых atool+соотв.распаковщиком) в 7z.
Теперь работает как надо. Чтобы не быть голословным, вот он:

Код: Выделить всё

#!/bin/bash
TMPDIR=anyto7z-`whoami`-tmp.$$
mkdir $TMPDIR || exit 1
cd $TMPDIR || exit 1

for FILE in "$@"; do
  echo "Processing $FILE..."
  aunpack "../$FILE" || exit 1
  apack "`ls`.7z" * || exit 1
  mv *.7z ../ || exit 1
  rm "../$FILE" || exit 1
  rm -rf * || exit 1
done

cd ..
rm -rf $TMPDIR
echo Done.

Может ещё чего посоветуете, в bash'е я не спец. :)
Но и на том спасибо.

watashiwa_darede...
да, так покороче :)
Спасибо сказали:

Аватара пользователя
diesel
Модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение diesel » 14.02.2009 14:44

watashiwa_daredeska писал(а):
14.02.2009 14:37

Код: Выделить всё

for f in "$@"; do
    echo "$f"
done

гы :) это был мой первый вариант, но забыл кавычки поставить в $@ :)

watashiwa_daredeska писал(а):
14.02.2009 14:37
diesel писал(а):
14.02.2009 14:21
Хотя постановка задачи мне кажется не очень правильной, по крайней мере непривычна - точно.
Нормальная постановка. Есть множествно программ, которые принимают произвольное число аргументов и выполняют над ними определенное действие. Для таких программ, в частности, и придуман xargs.

Множество программ - да. Чаще всего самописные скрипты с которыми приходится встречаться так не работают. Например, если бы я решал ту же задачу, то скрипту скармливалось бы просто имя файла, а фильтры оставались бы на съедение внешним циклам при запуске, хотя это дело вкуса.

rm_ писал(а):
14.02.2009 14:38
Да не в PHP дело... Ошибаетесь, если думаете что топик за этим был создан.

да не - просто переход на php какой-то резкий:)
Спасибо сказали:

Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение rm_ » 14.02.2009 14:56

Множество программ - да. Чаще всего самописные скрипты с которыми приходится встречаться так не работают.

Если "самописный" - это синоним "низкокачественный" или "сделанный за пять минут на коленке", тогда да. :)
Но удобно ведь, когда даже самодельные скрипты принимают аргументы точно так же, как и большие "взрослые" программы.
Вообще, зачем проводить какую-то границу между "программой" и "скриптом"? Если посмотреть внутрь очень многих "якобы программ", обнаружится, что писаны они на Perl'е или Python'е. Взять хоть тот же самый atool, который я использовал.

Код: Выделить всё

$ cat /usr/bin/atool
#!/usr/bin/perl -w
#
# atool - A script for managing file archives of various types.
...
Спасибо сказали:

watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение watashiwa_daredeska » 14.02.2009 15:09

rm_ писал(а):
14.02.2009 14:56
Вообще, зачем проводить какую-то границу между "программой" и "скриптом"?
В некоторых частностях они различаются, но для разработчика, а не для пользователя.

rm_ писал(а):
14.02.2009 14:56
Если посмотреть внутрь очень многих "якобы программ", обнаружится, что писаны они на Perl'е или Python'е.
Например, ОгнеЛис :)

user@host

$ file -L $(which firefox) /usr/lib/iceweasel/iceweasel: POSIX shell script text executable
Спасибо сказали:

Аватара пользователя
diesel
Модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение diesel » 14.02.2009 15:37

rm_ писал(а):
14.02.2009 14:56
Множество программ - да. Чаще всего самописные скрипты с которыми приходится встречаться так не работают.

Если "самописный" - это синоним "низкокачественный" или "сделанный за пять минут на коленке", тогда да. :)
Но удобно ведь, когда даже самодельные скрипты принимают аргументы точно так же, как и большие "взрослые" программы.
Вообще, зачем проводить какую-то границу между "программой" и "скриптом"? Если

"самописный" - это сделанный для себя, на коленке за пять минут - по сути это одна из основых функций/полезностей шелла как для пользователя - заскриптовать чего-нибудь для себя за пять минут. Должны ли они вести себя так же как "взрослые" - тот еще вопрос. Как по мне достаточно чтобы в случае необходимости можно было их связывать с другими программами. Конечно, это ИМХО, с другой колокольни оно совсем по-другому может смотреться. Для меня, например, когда скрипт отработал как надо в 80% случаев, а в остальных ничего не напортил - может быть полезно(причем даже когда напортил может быть полезно) - если же вдруг у вас 20% файлов не перепакуется - будет неприятно, посему относительно это все.
Спасибо сказали:

kotnaton
Сообщения: 228

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение kotnaton » 13.09.2011 02:50

Пытался по этой теме конвертировать в контейнер mp4 свои TS-ки:

for i in "$@/dos/TS/iii/*" ; do ffmpeg -i $i -vcodec copy -copytb -copyts -acodec copy -f mp4 '111/$i.avi' ; done

Вместо этого, программа просто переписала исходники, погубив мою видеоколлекцию, к несчастью, не было запасных копий.

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

liaonau
Сообщения: 390
ОС: gentoo

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение liaonau » 13.09.2011 03:59

kotnaton писал(а):
13.09.2011 02:50
for i in "$@/dos/TS/iii/*" ; do ffmpeg -i $i -vcodec copy -copytb -copyts -acodec copy -f mp4 '111/$i.avi' ; done
Вместо этого, программа просто переписала исходники, погубив мою видеоколлекцию, к несчастью, не было запасных копий.

После do сначала можно было echo вокруг ffmpeg написать. Уж сколько раз на форуме разговаривали о пробелах в именах, скрипты приводили рекурсивно переименовывающие пробелы в именах в «_» — а воз и ныне там.
Можно, например, так:

Код: Выделить всё

find -type f -print0|xargs -0 -I '{}' ffmpeg -i '{}' -vcodec copy -copyts -copytb -acodec copy '{}'.avi

О чем в этой теме упоминалось.

kotnaton писал(а):
13.09.2011 02:50
Прошу прощения просто накипело: это не первый, и не второй раз, пингвин теряет, то, что копилось месяцами... Спрашивается в задачнике: кому нужна такая ОС, с непонятным командным языком, да к тому же постоянно обновляемым, до состояния несовместимости ?

Причем здесь «пингвин» ☺? Поразительное заявление, феерично подменяющее понятия. Речь же исключительно об использовании оболочки и стандартных утилит. Если вам (лично вам, не всем же, разумеется) не понятен используемый вами командный язык, то не используйте его. Используйте другой. Оболочек, вообще-то много больше чем одна. Ну или perl, скажем, вполне можно запускать интерпретатором ☺.

А лучше просто выучите стандартный sh. А проще всего — не использовать пробелов в именах. Если переименовать нельзя — торрент, например, раздается, то есть же хардлинк — всего две буквы — ln.

А вообще, очевидно, что потеря чего-либо после команды пользователя — не есть потеря по вине ОС. Это ж не какой-нибудь баг в ФС, убивший данные.
Спасибо сказали:

kotnaton
Сообщения: 228

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение kotnaton » 13.09.2011 04:30

liaonau писал(а):
13.09.2011 03:59
на форуме разговаривали о пробелах в именах

К сожалению, это масса файлов была записана линуксовским же videolan-ом. Вручную все это проблематично переименовывать. Да и тупо конвертировать, чем-нибудь вроде transmageddon тоже нельзя: c тюнера идет не очень нестандартный TS, его надо сначало поместить в контейнер, хоть какой-нибудь. Хотя надо было и впрямь воспользоваться чем-нибудь вроде thunar --builk-rename

liaonau писал(а):
13.09.2011 03:59
find -type f -print0|xargs -0 -I '{}' ffmpeg -i '{}' -vcodec copy -copyts -copytb -acodec copy '{}'.avi

Спасибо за совет ! Попробую завтра на какой-нибудь никчемке. В самооправдании, замечу, что вещь не интуитивно понятная: хотя бы, тем, что внутрь фигурных скобох явно чего нибудь напрашивается, какая-нибудь маска имени файла.

liaonau писал(а):
13.09.2011 03:59
Это ж не какой-нибудь баг в ФС, убивший данные.

К сожалению, было и это: был и битый хард, с проблемой преусловутой парковки (hddparm -b 255, помните ?), была и нечитаемая ФС на ext4 (readonly), после очередного обновления, когда грешил на железо.

UPD: Еще раз спасибо, и... извините, если был резок.
бывает же такое ???
Спасибо сказали:

Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение rm_ » 13.09.2011 07:43

kotnaton писал(а):
13.09.2011 02:50
Вместо этого, программа просто переписала исходники, погубив мою видеоколлекцию, к несчастью, не было запасных копий.

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

Ололо, такие как вы попав молотком по пальцу, будут выступать за запрет молотков. "Спрашивается в задачнике": кому нужен такой юзер, который копит чего-то там месяцами, даже не делая бэкапов, потом по собственной глупости неосторожности это теряет, и обвиняет кого угодно, только не себя.
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение drBatty » 14.09.2011 22:00

rm_ писал(а):
14.02.2009 14:38
for FILE in "$@"; do

rm_ писал(а):
14.02.2009 14:38
Может ещё чего посоветуете, в bash'е я не спец.

что тут советовать, если (как я понял) $@ как раз и придумана для этого?!
kotnaton писал(а):
13.09.2011 02:50
Прошу прощения просто накипело: это не первый, и не второй раз, пингвин теряет, то, что копилось месяцами... Спрашивается в задачнике: кому нужна такая ОС, с непонятным командным языком

вы знаете, итальянский для меня тоже полностью не понятен. И что? Ругать можно тут лишь мою невежественность, а не итальянцев...
kotnaton писал(а):
13.09.2011 02:50
да к тому же постоянно обновляемым, до состояния несовместимости ?

а не надо читать маны 30и летней давности :)
bat-файлы из MS-DOS ещё более несовместимы с PowerShell Windows 6.x. Там вообще ничего общего нет. И что?
kotnaton писал(а):
13.09.2011 04:30
Вручную все это проблематично переименовывать. Да и тупо конвертировать

можно просто написать нормальный скрипт. И не забыть его протестировать.
kotnaton писал(а):
13.09.2011 04:30
что вещь не интуитивно понятная: хотя бы, тем, что внутрь фигурных скобох явно чего нибудь напрашивается, какая-нибудь маска имени файла.

напрашивается: туда как раз имя и подставляется. Без постороннего усилия, само по себе.
kotnaton писал(а):
13.09.2011 04:30
К сожалению, было и это: был и битый хард, с проблемой преусловутой парковки (hddparm -b 255, помните ?)

вас не предупредили, что это ОПАСНО?
(ага, большими буквами).
kotnaton писал(а):
13.09.2011 04:30
была и нечитаемая ФС на ext4 (readonly)

fsck
mount -o remount
Это такие тайные лечебные заклятья.
rm_ писал(а):
13.09.2011 07:43
который копит чего-то там месяцами, даже не делая бэкапов, потом по собственной глупости неосторожности это теряет, и обвиняет кого угодно, только не себя.

ИЧСХ - запускает мутные скрипты на ВСЕЙ незабекапленной коллекции, причём эти скрипты почти не понимая...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

kotnaton
Сообщения: 228

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение kotnaton » 02.08.2014 14:17

И всё-таки, хочу вернуться к своему предыдущему вопросу:
почему такая конструкция

Код: Выделить всё

for i in "*.ts" ; do ffmpeg -i $i -vcodec copy -acodec copy "2/$i.mkv" ; done

пытается перезаписывать исходные файлы, а не создавать новые ??? Как это исправить

А приводившаяся выше конструкция слишком мудра, но не дает выборки по маске:

Код: Выделить всё

$ find -type f -name *.ts -print0|xargs -0 -I '{}' ffmpeg -i *.ts -vcodec copy -acodec copy '{}'.mkv
find: paths must precede expression: 2014-07-01_19ч40м— оя запись.ts
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

бывает же такое ???
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15818
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение Bizdelnick » 02.08.2014 22:37

kotnaton писал(а):
02.08.2014 14:17
И всё-таки, хочу вернуться к своему предыдущему вопросу:
почему такая конструкция

Код: Выделить всё

for i in "*.ts" ; do ffmpeg -i $i -vcodec copy -acodec copy "2/$i.mkv" ; done

пытается перезаписывать исходные файлы, а не создавать новые ??? Как это исправить
Не должна она ничего перезаписывать. Покажите, что именно происходит.
Да, $i возьмите в двойные кавычки.

kotnaton писал(а):
02.08.2014 14:17
А приводившаяся выше конструкция слишком мудра, но не дает выборки по маске:

Код: Выделить всё

$ find -type f -name *.ts -print0|xargs -0 -I '{}' ffmpeg -i *.ts -vcodec copy -acodec copy '{}'.mkv
find: paths must precede expression: 2014-07-01_19ч40м— оя запись.ts
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
Такой бредовой конструкции никто выше не приводил. Ничего мудрого в ней нет, зато есть куча ошибок.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: bash-циклы по параметрам, и имена файлов с пробелами

Сообщение drBatty » 02.08.2014 23:23

kotnaton писал(а):
02.08.2014 14:17
for i in "*.ts"

здесь кавычки лишние.

в остальном согласен с Bizdelnick
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: