Давайте проанализируем ваш сценарий и попытаемся объяснить, почему он работает медленно.
Давайте начнем с микрооптимизации вашей первой строки. Это не собирается ускорять вещи, но это просто образовательный процесс.
cat /home/maillog |grep "Nov 13" |grep "from=<xxxx@xxxx.com>" |awk '{print $6}' > /home/output_1
В этой строке вы совершаете 4 вызова в разные двоичные файлы, которые в итоге могут быть выполнены одним. Для удобства чтения вы можете оставить эту строку. Тем не менее, вот два основных момента:
Бесполезное использование cat
. Программа cat
в основном используется для конкатенации файлов. Если вы просто добавите один файл, то это в основном излишне. Особенно, если вы хотите передать его grep
.
cat file | grep ... => grep ... file
несколько greps в сочетании с awk ... можно записать как один awk
awk '/Nov 13/ && /from=<xxxx@xxxx.com>/ {print $6}'
Таким образом, вся строка может быть записана как:
awk '/Nov 13/ && /from=<xxxx@xxxx.com>/ {print $6}' /home/maillog > /home/output_1
Во второй части все идет медленно:
while read line; do
awk -v line="$line" '$6 ~ line { print $0 }' /home/maillog >> /home/output_2 ;
done < /home/output_1
Почему это медленно? В каждой строке вы читаете форму /home/output_1
, загружаете программу awk
в память, открываете файл /home/maillog
, обрабатываете каждую его строку и закрываете файл /home/maillog
. В то же время для каждой обрабатываемой строки вы каждый раз открываете /home/output_2
, помещаете указатель файла в конец файла, записываете в файл и снова закрываете файл.
Вся программа фактически может быть выполнена с помощью одного awk:
awk '(NR==FNR) && /Nov 13/ && /from=<xxxx@xxxx.com>/ {a[$6];next}($6 in a)' /home/maillog /home/maillog > /home/output2