代码之家  ›  专栏  ›  技术社区  ›  Akshay Hazari

使用s3上的sed在两个日期之间搜索

  •  0
  • Akshay Hazari  · 技术社区  · 6 年前

    我正在尝试获取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 (不过滤任何内容) 这样做对吗?

    如有任何帮助,我们将不胜感激。

    更新

    按要求-Ravindersing13

    我使用了-n as,发现没有-n,sed命令充当cat命令。

    按照jhnc的建议,我添加了-n作为grep命令,它给了我空的结果。

    示例输入模式如下,结果为空

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

    使用added-n(作为grep使用),我在上面有一个bug,其中-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 回复  |  直到 6 年前
        1
  •  1
  •   jhnc    6 年前

    这个 sed 只有当开始日期出现在列表中时,问题中给出的代码才能正常工作。

    我们需要进行字符串比较,而不是regexp匹配。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}'
    
        2
  •  1
  •   tshiono    6 年前

    作为一个简单的(不带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)
    

    你会发现没有什么诀窍:它只是将日期格式转换成一个直的数字,然后用算术方法对它们进行比较。

        3
  •  0
  •   Akshay Hazari    6 年前

    同时我学了一点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}}'