bash скрипт цикл с условием

Для новичков как вообще в Linux, так и в конкретной теме, к которой относится вопрос.

Модератор: Bizdelnick

Ответить
safronowmax
Сообщения: 103

bash скрипт цикл с условием

Сообщение safronowmax »

Здравствуйте, подскажите пожалуйста, есть текстовый файл с данными myfile (3 столбца: Дата, Размер, Наименование), данные динамически меняются в файле. Необходимо отфильтровать строки по самой ранней дате, в отфильтрованных строках посчитать сумму по столбцу Размер и далее проверить - если суммарный размер по столбцу Размер больше 10000, то выводим сообщение "Размер больше 10000", а если суммарный размер по столбцу Размер меньше 10000, то выполняем в цикле предыдущие действия - отфильтровываем строки по самой ранней дате, считаем сумму по столбцу Размер и если суммарный размер больше 10000, то выход из цикла, а если меньше 10000, то все заново
Частично написал скрипт, но не пойму, как правильно написать цикл с условием. Сейчас скрипт выглядит так:

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

#!/bin/bash

# определяем самую раннюю дату в файле myfile
EARLIEST_DATE=`cat /root/myfile |awk '{print $1}' |sort |head -n 5 |tail -n 1`

# отфильтровываем все строки с этой самой ранней датой из файла myfile и выбираем только столбец с размером 
FILTER_STRINGS=`cat /root/myfile |grep $EARLIEST_DATE |awk '{print $3}' > $TMP_SIZE`

# суммируем размер за нашу дату
SUMMARY_SIZE=`cat $TMP_SIZE| awk '{s += $1} END {print s}'`

# проверяем, больше требуемого размера наш суммарный размер по столбцу Размер или нет 
if [[ $SUMMARY_SIZE -gt 10000 ]]; then
echo "Размер больше 10000"
  else 
    #здесь должен идти цикл с повторяющимися действиями, не пойму, как правильно написать
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 900
ОС: debian, fedora (i3-wm)

Re: bash скрипт цикл с условием

Сообщение olecya »

Все это можно вставить в бесконечный цикл:

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

while true; do
   <<ваш код>>
  if [ $SUMMARY_SIZE -gt 10000 ]; then
    echo "Размер больше 1000"
    break
  fi
  sleep 100
done
Но ваш код не верх совершенства. Вы вызываете awk только, для того чтобы выделить первое поле. Делайте тогда все в awk
Добавлено (13:27):
Покажите образец, формат одной строчки файла myfile, ну или хотя бы что представляет собой поле "дата"
Спасибо сказали:
safronowmax
Сообщения: 103

Re: bash скрипт цикл с условием

Сообщение safronowmax »

olecya, спасибо большое.
Вот пример строки из файла

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

Дата             Размер Наименование
2022-12-05    | 450 | пример1       | 
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 900
ОС: debian, fedora (i3-wm)

Re: bash скрипт цикл с условием

Сообщение olecya »

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

#!/bin/bash
while awk -F'[|[:blank:]]+' '
        BEGIN {PROCINFO["sorted_in"]="@ind_str_asc"}
        {A[$1]+=$2}
        END {for(i in A)if(A[i] > 1000)exit 1; exit}
        ' /root/myfile; do
        sleep 10 #время задержки 10 секунд перед следующим циклом
done
echo Размер больше 1000
Ну или если это часть чего-то большего. Определить размер самых ранних файлов:

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

SUMMARY_SIZE=$(awk -F'[|[:blank:]]+' 'BEGIN {PROCINFO["sorted_in"]="@ind_str_asc"} {A[$1]+=$2} END {for(i in A){print A[i]; break}}' /rooot/myfile)
Добавлено (15:38):
Или так, если это ГНУтый awk:

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

SUMMARY_SIZE=$(awk -F'[|[:blank:]]+' '{A[$1]+=$2} END {asorti(A, D); print A[D[1]]}' /root/myfile)
Добавлено (16:14):
safronowmax
Да, действительно. С разделителем FS я намудрила -F'[|[:blank:]]+'
Достаточно было, как вы сделали, просто вместо $2 поля поставить третье $3. Тогда все будет выглядеть совсем компактно и читабельно
Добавлено (16:21):

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

#!/bin/bash
while awk '
        BEGIN {PROCINFO["sorted_in"]="@ind_str_asc"}
        {A[$1]+=$3}
        END {for(i in A)if(A[i] > 10000)exit 1; exit}
        ' /root/myfile; do
        sleep 100 #время задержки 100 секунд перед следующим циклом
done
echo Размер больше 10000

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

SUMMARY_SIZE=$(awk 'BEGIN {PROCINFO["sorted_in"]="@ind_str_asc"} {A[$1]+=$3} END {for(i in A){print A[i]; break}}' /root/myfile)

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

SUMMARY_SIZE=$(gawk '{A[$1]+=$3} END {asorti(A, D); print A[D[1]]}' /root/myfile)
Спасибо сказали:
safronowmax
Сообщения: 103

Re: bash скрипт цикл с условием

Сообщение safronowmax »

olecya, спасибо вам большое!
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 900
ОС: debian, fedora (i3-wm)

Re: bash скрипт цикл с условием

Сообщение olecya »

olecya писала:
10.01.2023 15:25

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

END {for(i in A)if(A[i] > 10000)exit 1; exit}
Как не красиво получилось. Ошибку нашла:

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

END {for(i in A){if(A[i] > 1000)exit 1; exit}}
Добавлено (10:37):
Ну или так:

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

END {for(i in A)if(A[i] > 1000)exit 1; else exit}
Добавлено (10:48):
Да ну нафик! Чтобы не ошибаться:

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

END {for(i in A)exit (A[i] > 1000)}
Спасибо сказали:
Ответить