Когда нужно обработать большой поток данных, отфильтровать его и получить доступ к результатам как к массиву - простого grep уже мало. Тут на сцену выходит связка:
mapfile + grep + <(process substitution)
▪️ Цель: передать данные в массив, фильтруя на лету
mapfile -t matched_lines < <(grep "ERROR" /var/log/syslog)
<(…) - создает временный named pipegrep фильтрует строки по "ERROR"mapfile -t читает результат построчно в массив matched_lines▪️ Применение: разбираем большой лог
for line in "${matched_lines[@]}"; do
echo "Найдено: $line"
done
Под капотом нет временных файлов и лишней нагрузки. Всё работает в памяти и построчно, даже с огромными логами.
▪️ Расширение: фильтрация по нескольким условиям
mapfile -t critical < <(grep -E "FATAL|PANIC|OOM" /var/log/app.log)
Или постфильтрация:
mapfile -t filtered < <(some_command | grep -v DEBUG | grep -i error)
▪️ Пример из реального скрипта:
mapfile -t bad_ips < <(awk '{print $1}' access.log | sort | uniq -c | awk '$1 > 100 {print $2}')
В массив bad_ips попадают только IP, сделавшие >100 запросов.
BashTex 📱 #bash #utils