Вложенные циклы в bash - частая причина медленных скриптов при работе с большими массивами и файлами. Особенно если ты обрабатываешь 10000+ элементов и каждый проход делает grep, awk, cut, cat, sed...
▪️ Антипаттерн
for i in "${list1[@]}"; do
for j in "${list2[@]}"; do
if [[ "$i" == "$j" ]]; then
echo "Match: $i"
fi
done
done
➖ Это O(N²). Если массивы по 10к строк - будет 100 млн сравнений.
▪️ Оптимизация через associative array (Bash 4+)
declare -A lookup
# Заполняем хеш
for item in "${list2[@]}"; do
lookup["$item"]=1
done
# Ищем быстро
for i in "${list1[@]}"; do
if [[ ${lookup["$i"]+found} ]]; then
echo "Match: $i"
fi
done
➕ Это уже O(N). И в 1000 раз быстрее.
▪️ Ускорение чтения данных. Избавляемся от cat в цикле:
➖ Плохо:
while read line; do
cat "$line"
done < files.txt
➕ Лучше:
mapfile -t files < files.txt
for f in "${files[@]}"; do
cat "$f"
done
▪️ Убираем лишние циклы. Когда можно - переноси логику внутрь awk, grep, join, sort -m и т.д.
Пример: пересечение двух файлов без bash-циклов:
sort file1.txt file2.txt | uniq -d
BashTex 📱 #bash #utils