Читайте файл по одной строке за раз, затем сравнивайте сброшенные даты (в bash) - PullRequest
0 голосов
/ 02 ноября 2019

Я новичок в bash и сообществе в целом, поэтому, пожалуйста, потерпите меня.

Я пытаюсь создать простой скрипт, который:

  1. Читает текстовый файлстрока за строкой
  2. Соберите конкретную строку (в данном случае дату) из каждой строки и присвойте ее переменной
  3. Сравните ее с другой ранее определенной датой.
  4. Распечатайте всюстрока, если дата больше / меньше.

Вот как я пытаюсь ее достичь:

compareDate="$(date -d '2005-01-01' '+%Y-%m-%d')"

while read -r line;
do
date="$(grep -oP 'foo \K.*')"
if [[ $date < $compareDate ]];
echo $line 
then
continue
fi
done < text.txt

text.txt содержит:

foo 2000-01-01
foo 2002-01-01
foo 2004-01-01
foo 2005-01-01
foo 2006-01-01
foo 2007-01-01
foo 2008-01-01

Результат при выполнении:

./line.sh 
foo 2000-01-01

Точная проблема, я думаю, в том, что grep 'date' определяет весь текст, а не одну строку за раз:

mg@mg:~/bash -x line.sh 
++ date -d 2005-01-01 +%Y-%m-%d
+ compareDate=2005-01-01
+ read -r line
++ grep -oP 'foo \K.*'
+ date='2002-01-01
2004-01-01
2005-01-01
2006-01-01
2007-01-01
2008-01-01'
+ [[ 2002-01-01
2004-01-01
2005-01-01
2006-01-01
2007-01-01
2008-01-01 < 2005-01-01 ]]
+ echo foo 2000-01-01
foo 2000-01-01
+ continue
+ read -r line
m@mg:~$ 

Такжепосле того, как «дата» была выделена и правильно определена в цикле, я полагаю, что она должна быть преобразована в формат даты перед сравнением?

Я также попытался использовать awk вместо grep, но конечный результат был таким же.

Я, наверное, просмотрел все похожие темы по этому поводу, и я не удивлене, чего мне не хватает.

PS: я понимаю, что код, скорее всего, полон неправильного синтаксиса и форматирования, поэтому извиняюсь за это:)

Любая помощь очень ценится.

1 Ответ

0 голосов
/ 03 ноября 2019

Вы почти рядом. Как вы обнаружили, grep отбрасывает весь стандартный ввод, несмотря на то, что read пытается обрабатывать его построчно. Вместо этого вы можете явно передать переменную $line в grep с пометкой here string <<< "$line". Пожалуйста, попробуйте следующее:

compareDate="$(date -d '2005-01-01' '+%Y-%m-%d')"

while read -r line; do
    date="$(grep -oP 'foo \K.*' <<< "$line")"
    if [[ $date < $compareDate ]]; then
        echo "$line"
    fi
done < text.txt

Результат:

foo 2000-01-01
foo 2002-01-01
foo 2004-01-01

Кроме того, пожалуйста, поставьте строку echo "$line" между then и fi. В противном случае он будет вызван независимо от условия if.
Надеюсь, это поможет.

...