Shell Script - Awk Optimization

Chroot - более традиционный способ сделать это, и вы можете заставить его работать, но, поскольку вы делаете это через веб-интерфейс, он получает немного сложно: вы должны предотвратить условия гонки (несколько пользователей могут использовать одну и ту же среду chroot), вы должны динамически создавать структуру каталогов для каждого запроса и, возможно, еще несколько вещей, о которых я не могу придумать.

Если вы используете Linux, вам нужно посмотреть контейнеры ( lxc ) или проект Docker https://docs.docker.com . Платформа Docker, в частности, очень красиво и легко позволит вам делать то, что вы хотите здесь: создавать недолговечные, легкие виртуальные системы, которые можно использовать для запуска полностью заключенных в тюрьму процессов, не влияя на внешние (например, на ваш веб-сервер) ресурсы. Вы можете загрузить базовый образ докера для конкретной среды ОС, в которой должна запускаться программа (скажем, Fedora 12), указать докеру, что нужно запустить эту среду при импорте исходного кода вашей пользовательской программы в эту среду, а затем сказать докеру, что нужно запустить компилятор. и получившийся файл в этой среде. Затем вы приказываете докеру уничтожить эфемерное окружение. Ничего не остается позади, (почти) никакой угрозы безопасности.

3
29.01.2017, 23:35
2 ответа

Вы должны многого добиться, передав файл журнала только один раз через awk. Это означает объединение всех регулярных выражений в одно. Если вы не хотите делать это в файле scope.txt , сделайте это перед вызовом awk. Например,

sed <scope.txt 's|^/\^|(|; s|\$/$|)|; $!s/$/|/' | tr -d '\n' >pattern

zcat $file | bro-cut -d |
awk '
BEGIN{ getline pat <"pattern"; pat = "^(" pat ")$" }
$3 ~ pat || $5 ~ pat
'  >~/$file

sed заменяет / ^ и $ , окружающие каждую строку регулярного выражения, закрывающей парой () , добавляет | в конце строки и помещает результат в одну строку в файл pattern . Таким образом, в этом файле собраны все шаблоны вместе. Отсутствующий ^ (...) $ добавляется в оператор awk BEGIN сценария, который считывает файл шаблона в переменную pat .

Вышеупомянутый код заменяет ваш внутренний цикл for и sort | uniq .

6
27.01.2020, 21:11

Самый простой ответ - использовать scope.txt , очень немного измененный, как файл шаблона, и использовать zcat | grep (или просто zgrep ), чтобы получить нужные строки.

Сначала измените свой файл scope , изменив:

/^10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5])$/

на:

(^|[^0-9.])(10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5]))($|[^0-9.])

Чтобы сделать это легко, вы можете использовать:

sed -e 's:^/\^:(^|[^0-9.])(:' -e 's:\$/$:)($|[^0-9.]):' scope.txt > grepscope.txt

Затем выполните поиск:

zgrep -Ehf grepscope.txt /data/bro_logs/2016-11-26/conn.*.log.gz | less

Или, поскольку вы хотите, чтобы выходные данные для каждого файла сохранялись отдельно:

for f in /data/bro_logs/2016-11-26/conn.*.log.gz; do
    zgrep -Ehf grepscope.txt "$f" | sort -u > ~/"${f##*/}"
done

Обратите внимание, что переменная цикла for $ f будет содержать полный путь к каждому файлу по очереди; чтобы избежать ошибок, которые могут возникнуть, если мы попытаемся направить вывод в ~ / "$ f" (который будет относиться к подкаталогам ~ / data / bro_logs / 2016-11-26 , которые вероятно, не существует в вашем домашнем каталоге), мы удаляем все до последней косой черты в имени пути и просто используем базовое имя каждого файла журнала.


Флаги zgrep содержат упоминание:

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

-h подавляет печать имени файла в качестве префикса для каждой совпадающей строки. (Вы можете опустить это в версии цикла для , поскольку по умолчанию grep печатает имя файла только при поиске более чем одного файла, как в первой указанной мной команде, но это не так » Не повредит что-либо, чтобы сохранить это в обеих версиях.)

-f позволяет вам указать файл шаблона. Это именно то, что вам нужно, согласно вашему вопросу, и использование grep -f позволяет использовать несколько шаблонов поиска, взятых из файла, без создания команды Awk с огромным числом «или» с.


сортировать | uniq обычно можно заменить на sort -u , если вам не нужно использовать некоторые из флагов опций uniq . В данном случае нет, поэтому я использовал более простую форму sort -u .

2
27.01.2020, 21:11

Теги

Похожие вопросы