Как выполнить поиск по диапазону даты? - PullRequest
2 голосов
/ 04 апреля 2011

У меня файл журнала выглядит так:

2011-03-21 00:01 xxxx
2011-03-22 04:05 xxxx
....
2011-03-25 10:12 xxxx
....
2011-04-04 12:23 xxxx

Я хочу иметь скрипт, который требует 2 аргумента в качестве диапазона дат, например:

grep-date-range.sh 2011-03-25 2011-04-02

Он найдет все журналы в [2011-03-25, 2011-04-02]. Я знаю, что для конкретного случая я могу использовать подстановочный знак, но, на мой взгляд, он не является общим. Может ли кто-нибудь дать мне решение?

EDIT: Сценарий Python также приемлем.

Ответы [ 4 ]

3 голосов
/ 04 апреля 2011
sed -n "/$1/,/$2/p" $3

назовите это:

fromTo "2011-03-25" "2011-04-02" foo.log

СЭД

  • -n: нет вывода
  • / from /, / to /: шаблон для соответствия
  • p: печать

В файле должны существовать даты, они не будут работать, если вы просто указали в качестве даты 2011-03-24 и 2011-03-26. Это сопоставление строк, а не сопоставление дат. Вам не нужно цитировать, но у меня был другой формат даты, поэтому я использовал для своих тестов («23 марта» и т. Д.)

3 голосов
/ 04 апреля 2011

Это тот случай, когда лучше написать короткий скрипт на Python.Возможности высокоуровневых манипуляций с датами в языке могут быть полезны.

Сценарий, приведенный ниже, очень прост - с немного большей работой он может позаботиться о различиях во времени, летнем времени и т. Д.

#! /usr/bin/python
import sys
from datetime import datetime
d_format = "%Y-%m-%d"

try:
    start = datetime.strptime(sys.argv[1], d_format)
    end = datetime.strptime(sys.argv[2], d_format) 
except (TypeError, IndexError):
    sys.stderr.write("Example: grep-date-range.py 2011-03-25 2011-04-02 \n")

for line in sys.stdin:
    try:
        date = datetime.strptime(line.split()[0], d_format)
        # suit the <=, <, comparisons bellow to your needs:
        if start <= date < end:
            sys.stdout.write(line)
    except (ValueError, IndexError):
        pass 
1 голос
/ 04 апреля 2011

ОК, я наконец понял это.Основная идея состоит в том, чтобы объединить данные даты с помощью sort -m, чтобы извлечь эти известные строки обратно с помощью sed (благодаря предложению «user unknown»).Если файл данных еще не отсортирован, сначала отсортируйте его.Здесь предполагается, что YYYY-MM-DD является константой, иначе это не сработает.

Возможно, вы могли бы сделать это более надежным, используя mktemp вместо /tmp/startstop и более уникальную строкучем «START» и «END».

/tmp/data, очевидно, ваш файл данных.

#!/bin/bash

START=$1
END=$2

echo $START START > /tmp/startstop
echo $END END >> /tmp/startstop

sort -m /tmp/data /tmp/startstop | sed -n '/START/,/END/p'
0 голосов
/ 04 апреля 2011

хорошо, так как ваша дата уже "сортируемая",

#!/bin/bash

a=2011-03-25
b=2011-06-02
a=${a//-/} # you can remove the dashes or not, up to you
b=${b//-/} # you can remove the dashes or not, up to you
awk -va=$a -vb=$b '{
    # save the first field if going to remove dash, 
    old=$1 
    # you can remove the dashes or not, up to you. Because your date is sortable
    # the dash will not matter.
    gsub(/-/,"",old) # for removing dash
    if( old >= a && old <=b ){ 
        # or use if ($1 >=a && $1 <=b ) (if not removing dash)
        print
    }
}' file
...