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


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: bash и предотвращение подстановки масок...  (Прочитано 2656 раз)

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

Оффлайн AnrDaemon

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 28366
    • Просмотр профиля
Есть ядро скрипта, примерно такое:

#! /bin/sh
set -x

_LIST="$*"

for pattfile in $(dir -C "./exclude.list.d") ; do

  exec 100< "./exclude.list.d/${pattfile}"
  while read -u 100 pattern ; do
    _LIST="$_LIST ! -iname \'$pattern\'"
  done

done

find /home/$USER $_LIST > listfile

В каталоге exclude.list.d лежат файлы со списками масок (*.rar, *.zip, *.log и т.п. Одна маска на строку.)
Что я ни делаю, не могу добиться нормальной работы экранирования... результирующая команда получается либо нерабочей (маски заменяются списком файлов, под них попадающих), либо вообще нерабочей (Маски превращаются в помойку вида
'!' -iname ''\''*.iso'\'''
Можно сделать ЭТО нормально без использования более других средств, одним шеллом?
Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…

Оффлайн absent

  • Активист
  • *
  • Сообщений: 368
  • Ubuntu 16.04
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #1 : 06 Февраля 2013, 13:17:02 »
нужен список файлов с исключением по маске?
#!/bin/sh

list=""
for f in $(dir -C "./exclude.list.d"); do
    while read mask; do
        list="$list -not -iname $mask"
    done < "./exclude.list.d/$f"
done
find "/home/$USER" $list > listfile
работает без экранировок. правда на чистом шеле не получилось, используются dir find (хоть и без grep sed awk)
единственное условие - в файлах, содержащих маски, завершающим должен быть перевод строки, иначе маска не срабатывает.

Оффлайн AnrDaemon

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 28366
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #2 : 06 Февраля 2013, 13:47:29 »
absent, масок более 50, надо построить список файлов, не содержащих все маски.
В вашем случае получается ! -iname Full-2013-02-06.log вместо -iname *.log.
И синтаксис "-not pattern" непереносим.
« Последнее редактирование: 06 Февраля 2013, 13:50:13 от AnrDaemon »
Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…

Оффлайн absent

  • Активист
  • *
  • Сообщений: 368
  • Ubuntu 16.04
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #3 : 06 Февраля 2013, 16:19:13 »
В вашем случае получается ! -iname Full-2013-02-06.log вместо -iname *.log.
этот момент не понял, с чего вдруг? в listfile складируются все файлы за исключением тех масок, что указаны в файлах директории ./exclude.list.d
масок может быть хоть 1000
для примера, поместил в ./exclude.list.d кучу файлов
img log doc
и так далее, внутри них
log:
*.log
img:
*.jpg
*.png
*.svg
*.gif
*.jpeg
doc:
*.doc
*.odt
*.txt
*.rtf
и так далее
в listfile получаю список файлов, за исключением всех вышеперечисленных масок.
или я задачу не допонял?

Оффлайн AnrDaemon

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 28366
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #4 : 06 Февраля 2013, 22:02:57 »
C того, что в каталоге оказался файл Full-2013-02-06.log, и при передаче списка команде find маска *.log была расширена до списка соответствующих файлов в текущем каталоге.
Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: bash и предотвращение подстановки масок...
« Ответ #5 : 07 Февраля 2013, 07:06:06 »
Придумалось самое простое: замена "/*/ASTERISK/" при чтении и обратная замена при оформлении результата.

Оффлайн AnrDaemon

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 28366
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #6 : 07 Февраля 2013, 17:46:27 »
Интересный вариант...
Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…

Оффлайн AnrDaemon

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 28366
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #7 : 09 Февраля 2013, 14:03:47 »
ArcFi, всё равно не работает. Читая man bash, создаётся впечатление, что авторы сделали всё возможное, чтобы подобные вещи было невозможно сделать.
« Последнее редактирование: 09 Февраля 2013, 14:08:39 от AnrDaemon »
Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: bash и предотвращение подстановки масок...
« Ответ #8 : 09 Февраля 2013, 19:56:54 »
А если убрать дополнительное экранирование, то кажись, работает:
$ head -n100 exclude.list.d/* find.sh
==> exclude.list.d/doc <==
*.doc
*.odt
*.txt
*.rtf

==> exclude.list.d/img <==
*.jpg
*.png
*.svg
*.gif
*.jpeg

==> exclude.list.d/log <==
*.log

==> find.sh <==
#! /bin/sh
#set -x

_LIST="$*"

for pattfile in $(dir -C "./exclude.list.d") ; do

  exec 100< "./exclude.list.d/${pattfile}"
  while read -u 100 pattern ; do
    _LIST="$_LIST ! -iname '$pattern'"
  done

done

echo "find /home/$USER $_LIST > listfile"

$ ./find.sh
find /home/arcfi ! -iname '*.doc' ! -iname '*.odt' ! -iname '*.txt' ! -iname '*.rtf' ! -iname '*.jpg' ! -iname '*.png' ! -iname '*.svg' ! -iname '*.gif' ! -iname '*.jpeg' ! -iname '*.log' > listfile

Оффлайн AnrDaemon

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 28366
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #9 : 09 Февраля 2013, 20:26:41 »
Да, если делать echo - всё супер...
Попробуй напрямую это исполнить...
Ладно, я [censored] [censored]. Буду в файл вываливать и исполнять уже оттуда. Такой себе макродвижок, блин.
Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: bash и предотвращение подстановки масок...
« Ответ #10 : 09 Февраля 2013, 21:17:45 »
Убрал ещё одни кавычки.
По-моему, теперь работает:
Код: (bash) [Выделить]
$ cat find.sh
#! /bin/sh
set -x

_LIST="$*"

for pattfile in $(dir -C "./exclude.list.d") ; do

  exec 100< "./exclude.list.d/${pattfile}"
  while read -u 100 pattern ; do
    _LIST="$_LIST ! -iname $pattern"
  done

done

find /home/$USER/test $_LIST > listfile

$ ls -1 test
1.abc
1.doc
1.jpeg
1.pdf

$ cat listfile
/home/arcfi/test
/home/arcfi/test/1.pdf
/home/arcfi/test/1.abc

Оффлайн AnrDaemon

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 28366
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #11 : 09 Февраля 2013, 22:35:45 »
ArcFi, вернулись к тому, с чего начали. При передаче $_LIST на выполнение, если в текущем каталоге есть файлы, попадающие под маски, вместо маски подставляется список файлов.
Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: bash и предотвращение подстановки масок...
« Ответ #12 : 09 Февраля 2013, 23:09:36 »
При передаче $_LIST на выполнение, если в текущем каталоге есть файлы, попадающие под маски, вместо маски подставляется список файлов.
Эх, точно...
Ну, есть и иные варианты:
Код: (bash) [Выделить]
find test/ -regextype posix-extended ! -iregex "$(cat ./exclude.list.d/* | xargs | sed 's/\./\\./g;s/*/.*/g;s/ /|/g')"%)

Оффлайн AnrDaemon

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 28366
    • Просмотр профиля
Re: bash и предотвращение подстановки масок...
« Ответ #13 : 09 Февраля 2013, 23:25:43 »
Заррраза!... Не хотел я регэкспы делать. Это серьёзно медленнее работает. (Файлопомойка на 160 гигов, средний размер файла 2 метра.)
Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: bash и предотвращение подстановки масок...
« Ответ #14 : 10 Февраля 2013, 05:02:11 »
Это серьёзно медленнее работает.
Тогда можно вернуться к предыдущему варианту...
Код: (bash) [Выделить]
#! /bin/sh
set -x

_LIST="$*"

for pattfile in $(dir -C "./exclude.list.d") ; do

  exec 100< "./exclude.list.d/${pattfile}"
  while read -u 100 pattern ; do
    _LIST="$_LIST ! -iname '$pattern'"
  done

done

sh -c "set -x ; find /home/$USER $_LIST > listfile"
На моём тестовом наборе отработало нормально.

 

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