циклы в bash

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

Модератор: Bizdelnick

melaniewalker
Сообщения: 1
ОС: window 10

циклы в bash

Сообщение melaniewalker »

Друзья, нужна помощь.
есть задача найти в файле искомое значение и если такой строки нет, то искать ближайшее занчение.
я понимаю как проверить наличие строки в файле - grep -q "${start}" myfile.txt
я понимаю как из даты вычесть необходимое мне время - date --date=''$start' 1 minutes ago' '+%Y-%m-%d %H:%M'
но я никак не пойму как мне все это загнать в цикл.
Т.е. должно выглядеть типа:
#!/bin/bash
#вводим значение
read start
#дальше идет цикл, который
#проверят наличие строки и если она есть пишет ок
# если такой строки нет, вычитает из из $start одну минуту и проверяет наличие получившегося значения в файле,
если таковое значение есть, выдает переменную с таким значением и печатает содержимое этой переменной.
# если такого значения снова не оказалось, то вычитает еще одну минуту и снова проверяет и так до тех пор пока не найдет совпадение.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21387
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: циклы в bash

Сообщение Bizdelnick »

А в чём проблема? В цикле делаете start=$( date --date="$start 1 minute ago" '+%Y-%m-%d %H:%M' ) и грепаете.
Только я бы предварительно ещё корректность введённого времени проверил, вроде

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

format='+%Y-%m-%d %H:%M' 

read start
start=$( date --date="$start" "$format" )
if [ $? -ne 0 ]; then
  echo "invalid time" >&2
  exit 1
fi

while ! grep -qF "${start}" myfile.txt; do
  start=$( date --date="$start 1 minute ago" "$format" )
done

echo "$start"
Что требуется вывести, я не понял, исправьте в соответствии со своими нуждами.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 904
ОС: debian, fedora (i3-wm)

Re: циклы в bash

Сообщение olecya »

melaniewalker писал(а):
23.08.2023 13:20
#дальше идет цикл, который
#проверят наличие строки и если она есть пишет ок
# если такой строки нет, вычитает из из $start одну минуту и проверяет наличие получившегося значения в файле,
если таковое значение есть, выдает переменную с таким значением и печатает содержимое этой переменной.
# если такого значения снова не оказалось, то вычитает еще одну минуту и снова проверяет и так до тех пор пока не найдет совпадение.
Если это алгоритм не из задания, то он составлен очень неудачно. Перечитывать каждый раз файл и сравнивать с новым значением то еще занятие. Лучше сделать в одном цикле. Так как примера строки я не вижу, представлю что строки состоят только из приведенного вами формата даты:

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

 #!/bin/bash
read -p "Введите время в формате: $(date '+%Y-%m-%d %H:%M')"$'\n> ' start
round=" no approximate data"

while read line; do
	if [ "$line" = "$start" ]; then
		echo Ok
		exit
	fi
	if [ "$line" \< "$start" -a "$line" \> "$round" ]; then
		round="$line"
	fi
done <file
echo $round
Если работа скрипта на этом не заканчивается то, следует поместить этот код в функцию, а exit заменить на return
Добавлено (17:56):
Если строки файла сложнее и даты надо предварительно выделить, то замените строку:
olecya писала:
23.08.2023 17:31
done <file
на:

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

done < <(grep -o '[12][0-9][0-9][0-9]-[01][1-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]' file)
Спасибо сказали: