Вопрос по bash-scripting (переменные и подстановка)

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

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
Sparky
Сообщения: 604
Статус: core dumped
ОС: Plan 9

Re: Вопрос по bash-scripting

Сообщение Sparky »

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

time for i in `seq 1000`; do echo "1 555[123] 000"; done | perl -nle 'print$1if/\[(\d+)\]/' > /dev/null

А это разве не конвеер?
Блог
--------------------

GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
Спасибо сказали:
uZer
Сообщения: 100

Re: Вопрос по bash-scripting

Сообщение uZer »

спасибо, работает, но все равно недопонял:

Warderer писал(а):
26.01.2006 11:57
\(<выражение>\) - выделение совпадения в переменную


совпадения с чем?



Warderer писал(а):
26.01.2006 11:57
\1 - переменная, полученная скобками (на две строки выше)


имя переменной?
Спасибо сказали:
Nab
Сообщения: 257

Re: Вопрос по bash-scripting

Сообщение Nab »

Следил я за этим замечательным топиком, почерпнул много интересного....
А учитывая что именно сейчас сижу и уже которые сутки пишу парсинг XML на shell :)
Скажу сразу, первые результаты меня удручили очччень сильно, именно в плане производительности :(

Обрисую задачу:
Как известно я тут без фриски своей жить не могу :) и посему собираю и дополняю к ней всякий софт нужный и не очень.
И вот имея Squid и желая прикрутить к нему Режик, дабы уменьшить количество закачиваемого хлама, я столкнулся с парой неприятных моментов. Режик хорош в первую очередь DBL, распределенный банлист, пополняемый самими участниками системы, имеющим рейтинговую основу.
Но при том что режик наверно самый быстрый редиректор, DBL является XML файлом определенной структуры. Что понятное дело сильно увеличивает его размер. DBL имеет размер 11Мб тогда как содержащиеся в нем правила всего 600Кб.
Так вот для его разбора и формирования локальных банлистов используется модуль написанный на перл с использованием XML::Parser. Это немного не подходит. К сожаленью в стандартной поставке этого модуля нет. А ставить дополнительные модуля на фриску не очень просто, практически вообще невозмножно, только скомпилив и перенеся с родительской системы, что не хотелось делать.
А учитывая что я хотел собрать самодостаточный пакет, без использования каких либо внешних прог, то и решил произвести разбор XML на шелле, благо формат там весьма простой, и особого изврата нет...
Нет вы не подумайте, я и не собирался писать универсальный парсер :) только под конкретную задачу.

Первый результат меня убил, разбор. именно пока только разбор на моей машине P 233 занял более 11 часов :( а это еще не самая трудоемкая задача. Там необходимо было еще сформироать из результатов разбора окончалеьное множество Это когда из существующий списка вычитается список удаляемых банов и добавляется новые, и при этом они не должны пвторятся. Короче задача не из легких. Хотя я и с ней справился :) То есть уже существует полная реализация управления DBL листом на shell.
Жутко медленная правда :( Но задача-минимум решена.

Теперь задача-максимум.
Первое, то что я перешел с Sarg на LightSquid, использующий перл подтолкнуло меня к решению той же задачи на перле, но без юзания пары внешних либ XML::Parser и Text::Iconv используемых в оригинале.

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

Теперь о приятном. Решив эту задачу, я ессно не остановился. И решил подвергнуть оптимизации и шелл скрипты. В особенности меня на это подтолкнули результаты тестирования приведенные в этом топике :) Итого вместа вызова в цикле sed для разбора строки, все было пущено сквозь хитрый конвейер, с последующим разбором намного более простых строк по сравнению с XML. Результат обнадежил. Первый скрипт из комплекта режика, показывающий статистику дал такие результаты:

команда такая: time скрипт list.dbl

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

SLOW***********************************
banner.urls - 86 records
web-mail.urls - 2 records
16.39user 38.25system 1:00.44elapsed 90%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (321845major+116844minor)pagefaults 0swaps


FAST***********************************
banner.urls - 86 records
web-mail.urls - 2 records
1.03user 1.67system 0:02.73elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (17857major+5370minor)pagefaults 0swaps

PERL***********************************
banner.urls - 86 records
web-mail.urls - 2 records
0.03user 0.03system 0:00.96elapsed 6%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (463major+72minor)pagefaults 0swaps

Там три вызова, один со старым скриптом, второй с новым, и третий перловый.
Файл немного укорочен :).
Результаты говорят сами за себя.

Вот результат работы быстрого скрипта на шелл и перлового на полном DBL листе

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

# time dbl_stat.sh list.dbl;  time dbl_stat.pl list.dbl

banner.urls - 2690 records
porno.urls - 28392 records
web-mail.urls - 1324 records
banner.pcre - 45 records
audio-video.pcre - 10 records
audio-video.urls - 102 records
warez.urls - 134 records
web-proxy.urls - 125 records
icq.pcre - 3 records
icq.urls - 36 records
spyware.urls - 204 records
chats.urls - 120 records
online-games.urls - 182 records

426.95user 913.30system 23:12.16elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (9128403major+2558445minor)pagefaults 0swaps


warez.urls - 134 records
web-proxy.urls - 125 records
audio-video.urls - 102 records
spyware.urls - 204 records
icq.pcre - 3 records
banner.urls - 2690 records
online-games.urls - 182 records
audio-video.pcre - 10 records
web-mail.urls - 1324 records
chats.urls - 120 records
icq.urls - 36 records
banner.pcre - 45 records
porno.urls - 28392 records

4.64user 0.25system 0:04.99elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (306major+78minor)pagefaults 0swaps


Кстати время работы оригинального скрипта учета статистики на перле использующего XML::Parser в 7~8 раз больше.


Из всего вышесказанного можно сделать вывод, что на скорость оччень влияют накладные расходы вызова программ, открывания и закрывания файлов.

Некоторые нюансы и причины я описал у себя Nablog, возможно будет немного понятнее.

Хотя самая сложна задача для меня оказалось написать верно скрипт который бы производил вычисления на шелле. Именно по теме топика, но как оказалось проблема не во мне. А втом что я ю зал два разных шелла немного не совместимых друг с другом в плане eval и expr. Первый это Ash 0.2a, маленький шелл который используется в Фриске. Другой bash второй версии. Добившись работы скрипта на одной машине, на второй полезли удивительные результаты, хотя ошибку не выдавал, но я так понял складывал адреса переменных а не переменные :). Добившись работы здесь, на фриске полезли ошибки. Я не мог понять почему. Но была поставлена задача, найти универсальное решение, и оно было найдено. :) с хитрой подстановкой и двойным eval. :) Если захотите выложу результаты и мои мытарства.
Чтобы правильно задать вопрос, нужно знать больше половины ответа...
FREESCO in Ukraine
Спасибо сказали:
Аватара пользователя
madskull
Сообщения: 1019
Статус: Экс-металлюга

Re: Вопрос по bash-scripting

Сообщение madskull »

uZer писал(а):
27.01.2006 00:05
спасибо, работает, но все равно недопонял:

Warderer писал(а):
26.01.2006 11:57

\(<выражение>\) - выделение совпадения в переменную


совпадения с чем?

С регекспом внутри скобок.

uZer писал(а):
27.01.2006 00:05
Warderer писал(а):
26.01.2006 11:57

\1 - переменная, полученная скобками (на две строки выше)


имя переменной?

?
Не понятен вопрос.


Nab писал(а):
27.01.2006 07:03
Из всего вышесказанного можно сделать вывод, что на скорость оччень влияют накладные расходы вызова программ, открывания и закрывания файлов.

Именно. Естесственно, что perl -wle 'for(1..1000){print "Hi"}' будет работать быстрее, чем for i in `seq 1000`; do perl -wle 'print "Hi"' ;done
ArchLinux / IceWM
Спасибо сказали:
Аватара пользователя
kapa
Сообщения: 143

Re: Вопрос по bash-scripting

Сообщение kapa »

простите, ради бога, но ничего не понимаю:

читаю Advanced Bash-Scripting Guide:

"variable1=`<file1` # Записать в переменную "variable1" содержимое файла "file1".
variable2=`cat file2` # Записать в переменную "variable2" содержимое файла "file2"
."

делаю:

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

date '+%u' > /var/log/date/test
A='</var/log/date/test'
echo "$A"


имею:
</var/log/date/test

вторым способом - тоже самое

поясню, циферка эта мне нужна для последующего пристыковывания к имени файлов в скрипте для ротации логов
Спасибо сказали:
Аватара пользователя
agent-mega
Сообщения: 505
Статус: Автономный модуль

Re: Вопрос по bash-scripting

Сообщение agent-mega »

Не ', а `.
DEBIAN & DEBIAN-BASED ONLY

Всё относительно. Объективности не существует.
Спасибо сказали:
Аватара пользователя
kapa
Сообщения: 143

Re: Вопрос по bash-scripting

Сообщение kapa »

agent-mega писал(а):
10.02.2006 00:00
Не ', а `.

вот спасибо!
с такой глупостью мучался
всё замечательно получилось
впредь буду внимательней :)
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Вопрос по bash-scripting

Сообщение t.t »

Кстати, вместо вот этих двух строчек

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

date '+%u' > /var/log/date/test
A=`</var/log/date/test`
можно использовать просто `date '+%u'` вместо $A там, где нужно вставлять "циферку".
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали: