как управлять датами в оболочке - PullRequest
0 голосов
/ 23 сентября 2011

У меня есть файл, содержащий 14000 дат.Я написал скрипт, чтобы найти последние 5 дней,

26/03/2002:11:52:25
27/03/2002:11:52:25
29/03/2002:11:30:41
30/03/2002:11:30:41
26/03/2002:11:30:41
02/04/2002:11:30:41
03/04/2002:11:30:41
04/04/2002:11:30:41
05/04/2002:11:52:25
06/04/2002:11:52:25

предположим, что это файл, теперь у меня есть дата 02/04/2002: 11: 30: 41 в качестве выхода.Я хочу поместить даты с 02/04/2002 до конца файла в другой файл.

start-date = 02/04/2002 (this is my start date) 
while [start-date lt end-date] do (while start date is less than end date )
start-date++ ( add one day to start day so if its 2/4/2002 it will become 3/4/2002)
echo $start-date|tee -a file1  (put it in a file)

этот код предполагает это, но у него есть проблема!Зачем?

grep -n $SDATE thttpd.log | cut -d: -f1 (pattern=$SDATE)
sed '/$SDATE/=' thttpd.log
awk '/$SDATE/{ print NR }' thttpd.log
$ sed -n "$(awk '$SDATE/ { print NR }' input),$ p" thttpd.log
$ awk 'NR >= line_number' line_number=$(grep -n $SDATE -m 1 thttpd.log | cut -d: -f1) thttpd.log

Ответы [ 6 ]

2 голосов
/ 23 сентября 2011

Предполагается, что файл отсортирован по дате и времени:

 sed -n '\.^02/04/2002.,$p' dates.list > results.list

Печать с первой строки, начинающейся с 02/04/2002, до конца файла.

0 голосов
/ 10 апреля 2012

Я написал целый набор инструментов ( dateutils ) для решения подобных проблем.В вашем случае это просто:

dgrep -i '%d/%m/%Y:%H:%M:%S' '>=02/04/2002:11:30:41' < FILE

, где опция -i указывает формат ввода, а >=02/04/2002:11:30:41 - ваша дата отсечения (>= означает даты моложе, чем указано, конечно).

0 голосов
/ 24 сентября 2011
awk -F"/|:" '{print $3$2$1}' File_Name|sort -u| tail -5
0 голосов
/ 23 сентября 2011

программно, вы можете найти пятый последний день, как это:

startdate=$( cut -d: -f1 filename | sort -u -t/ -k3 -k2 -k1 | tail -5 | head -1 )

Затем вы можете распечатать все дни, которые больше или равны этому дню:

awk -F: -v start="$startdate" '
  BEGIN { split(start, s, "/"); sdate=s[3] s[2] s[1] } 
  { split($1, d, "/");  if (d[3] d[2] d[1] >= sdate) print }
' filename
0 голосов
/ 23 сентября 2011

Я не использовал его сам, но команда gawk (AWK GNU) может манипулировать строками даты / времени . И gawk - это Linux-версия команды awk.

Вы также можете переписать всю программу в виде одного сценария awk. Это может сделать все намного проще. Помните, awk - полноценный язык программирования, который просто предполагает цикл чтения файла и обрабатывает каждую строку файла.

0 голосов
/ 23 сентября 2011

Это то, что вы хотите?

#!/bin/bash
# presumes GNU date

# input date format won't be understood by GNU date
# reformat, then return date as seconds
reformat_date(){
    year=$(cut -d/ -f3<<<$(cut -d : -f1 <<<"$1"))
    month=$(cut -d/ -f2<<<$(cut -d : -f1 <<<"$1"))
    day=$(cut -d/ -f1<<<$(cut -d : -f1 <<<"$1"))

    hour=$(cut -d : -f2 <<<"$1")
    min=$(cut -d : -f3 <<<"$1")
    sec=$(cut -d : -f4 <<<"$1")

    date +%s -d "$(printf '%s-%s-%s %s:%s:%s' "$year" "$month" "$day" "$hour" "$min" "$sec")"
}

from=$(reformat_date "$1")

flag=
while IFS= read -r d ; do
    d_s=$(reformat_date "$d")
    if [ -z $flag ] && [ $(expr "$d_s" - "$from") -gt 0 ] ; then
            flag=1
    fi

    if [ ! -z $flag ] ; then
            printf '%s\n' "$d"
    fi
done < "$2"

Сохранить как скрипт, передайте дату ввода в качестве первого аргумента и имя файла для обработки в качестве второго аргумента. Выводит строки из файла, которые появляются после первой строки позднее даты и времени ввода (включая первую строку).

So

./dates_from.sh '2/04/2002:11:30:41' dates.list > results.list

Псевдокод, который вы разместили, похоже, не соответствует описанию предыдущего предложения, поэтому я проигнорировал его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...