Поиск между двумя датами с помощью sed на s3 - PullRequest
0 голосов
/ 04 февраля 2019

Я пытаюсь получить все файлы между двумя датами на s3 -

aws s3 ls 's3://big-data-analytics-prod/LZ/copycat/emailstats/' --recursive |  sed  "/2018-06-01/,/`date +%Y-%m-%d -d '30 days ago'`/p"

Это дает мне все данные.Использовал это, но это не работает - https://stackoverflow.com/a/29412898/2251058 (ничего не фильтрует) Это правильный способ сделать это.

Любая помощь с этим приветствуется.

Обновления

По запросу - RavinderSingh13

Я использовал -n как и нашел без -n, команда sed действует как команда cat.

Как предложеноjhnc Я добавил -n для использования в качестве команды grep, и он дает пустой результат

Пример шаблона ввода - это что-то вроде следующего с пустым результатом

2018-06-01 13:32:20      <filesize> <filepath>....gz
.
.
.
.
2019-02-04 00:13:12      12344 <filepath>....gz

С добавленным -n (для использования в качествеgrep), у меня была ошибка выше, где -n не использовался, он не показывает никакого вывода.Для проверки я использовал следующие команды.Это не дает вывода.

echo "2018-01-01" |  sed -n "/2018-06-01/,/`date +%Y-%m-%d -d '30 days ago'`/p"
echo "2019-01-01" |  sed -n "/2018-06-01/,/`date +%Y-%m-%d -d '30 days ago'`/p"
echo "2019-02-01" |  sed -n "/2018-06-01/,/`date +%Y-%m-%d -d '30 days ago'`/p"
echo "2019-02-01" |  sed -n  "/2018-06-01/,/2019-01-05/p"
echo "2019-06-30" |  sed -n  "/2018-06-01/,/2019-01-05/p"

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

Тем временем я изучил немного awk и вместо этого использовал awk для вычисления этого, но забыл поделиться как ответ.

endtime=`date +%Y-%m-%d -d '-30 day'`
begintime="2018-06-01"
bucket="s3://big-data-analytics-prod/"
path='s3://big-data-analytics-prod/LZ/copycat/emailstats/'
aws s3 ls path --recursive  |  awk '{if($1>=$begintime && $1<=$endtime) {print $4} }'

ИЛИ в строке

aws s3 ls 's3://big-data-analytics-prod/LZ/copycat/emailstats/' --recursive  |  awk -v begintime="2018-06-01" -v endtime="`date +%Y-%m-%d -d '30 days ago'`"  '{if($1>=begintime && $1<=endtime) {print $4}}'
0 голосов
/ 04 февраля 2019

В качестве простого (без sed) решения попробуйте следующее:

#!/bin/bash

# usage: thiscommand startdate enddate
#    starddate and enddate should be in the format: yyyy-mm-dd

start=${1//-/}
end=${2//-/}

while read -r date rest; do
    date2=${date//-/}
    if ((start <= date2 && date2 <= end)); then
        echo "$date $rest"
    fi
done < input.txt

, где пример файла input.txt выглядит следующим образом:

2018-06-01 13:32:20      <filesize> <filepath>....gz
2019-01-01 01:23:45      <filesize> <filepath>....gz
2019-01-30 00:22:45      <filesize> <filepath>....gz
2019-02-01 11:03:05      <filesize> <filepath>....gz
2019-02-02 02:24:55      <filesize> <filepath>....gz
2019-02-04 00:13:12      12344 <filepath>....gz

Затем вызовитескрипт с:

$ ./thisscript 2019-01-01 2019-02-02

выход:

2019-01-01 01:23:45      <filesize> <filepath>....gz
2019-01-30 00:22:45      <filesize> <filepath>....gz
2019-02-01 11:03:05      <filesize> <filepath>....gz
2019-02-02 02:24:55      <filesize> <filepath>....gz

Если вы хотите обработать вывод команды aws напрямую, вы можете сказать:

#!/bin/bash

# usage: thiscommand startdate enddate
#    starddate and enddate should be in the format: yyyy-mm-dd

start=${1//-/}
end=${2//-/}

while read -r date rest; do
    date2=${date//-/}
    if ((start <= date2 && date2 <= end)); then
        echo "$date $rest"
    fi
done < <(aws s3 ls 's3://big-data-analytics-prod/LZ/copycat/emailstats/' --recursive)

Вы увидите, что здесь нет хитрости: он просто конвертирует формат даты в прямые числа и сравнивает их арифметически.

0 голосов
/ 04 февраля 2019

Код sed, приведенный в вопросе, будет работать правильно только в том случае, если в списке появится начальная дата.

Нам нужно проводить сравнения строк, а не сопоставлять регулярные выражения.Доступны либо awk, либо perl.

Необычный perl:

#!/usr/bin/perl

# Usage: $0 date1 date2
# where dates can be anything supported by date(1)
# remember to "quote whitespace"

# fancy date parsing
open(my $cmd, '-|', 'date', '+%Y-%m-%d %H:%M:%S', '--date', $ARGV[0]||'1970-01-01') or die $!;
my $start = <$cmd>;
chomp $start;
close $cmd;
open(my $cmd, '-|', 'date', '+%Y-%m-%d %H:%M:%S', '--date', $ARGV[1]||'now') or die $!;
my $end = <$cmd>;
chomp $end;
close $cmd;

# start should be earlier than end
($start, $end) = ($end, $start) if $start gt $end;

while (<STDIN>) {
    print if $_ ge $start && $_ le $end;
}

Простой awk (может вставлять дату звонка так же, как в оригинальном sed):

awk '$0>="2018-06-01" && $0<="2019-01-01" {print}'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...