如何在bash中输出两个日期之间的数据?

如何在bash中输出两个日期之间的数据?,bash,perl,loops,logfile,Bash,Perl,Loops,Logfile,我有这样一个文件: 2014-12-31 531.252429 532.602384 525.802363 526.402397 1368200 526.402397 2014-12-30 528.092396 531.152424 527.132366 530.422394 876300 530.422394 2014-12-29 532.192446 535.482414 530.013375 530.332426 2278500 530.332426 2014-12-26 528.7724

我有这样一个文件:

2014-12-31 531.252429 532.602384 525.802363 526.402397 1368200 526.402397
2014-12-30 528.092396 531.152424 527.132366 530.422394 876300 530.422394
2014-12-29 532.192446 535.482414 530.013375 530.332426 2278500 530.332426
2014-12-26 528.772422 534.252417 527.312364 534.032454 1036000 534.032454
2014-12-24 530.512424 531.761394 527.022384 528.772422 705900 528.772422
2014-12-23 527.00237 534.56241 526.292354 530.592416 2197600 530.592416
并希望以bash脚本回应2014-12-31和2014-12-23之间的每一行

我以前试过这个,但它最终向我展示了我想要的台词,但这是一个永无止境的循环

perl -ne 'if ( m/^([0-9-]+)/ ) { $date = $1; print if ( $date ge "2014-12-31" and $date le "2014-12-23" ) }' file.txt

出了什么问题以及如何修复代码?

如果行是按日期排序的,您只需使用Perl的

要修复一条线性,请交换
le
ge
运算符以正确设置范围:

perl -ne 'if ( m/^([0-9-]+)/ ) { $date = $1; print if ( $date le "2014-12-31" and $date ge "2014-12-23" ) }' file.txt

您正在打印日期在开始日期之前、结束日期之后的记录。
您应该打印日期在开始日期之后、结束日期之前的记录。
要修复此问题,只需翻转日期即可:

perl -ne'if ( m/^([0-9-]+)/ ) { $date = $1; print if ( $date ge "2014-12-23" and $date le "2014-12-31" ) }'
较短版本:

perl -ane'print if $F[0] ge "2014-12-23" && $F[0] le "2014-12-31"'

我不得不说,我可能会通过将时间和日期戳解析为大纪元,然后比较它们来解决这个问题

比如:

#!/usr/bin/env perl
use strict;
use warnings;

use Time::Piece;
my $end = Time::Piece->strptime( "2014-12-31", "%Y-%m-%d" );
my $start = Time::Piece->strptime( "2014-12-23", "%Y-%m-%d" );

while ( <DATA> ) {
    my $t = Time::Piece->strptime( (split)[0], "%Y-%m-%d" );
    print if $t > $start and $t < $end;
}

__DATA__
2014-12-31 531.252429 532.602384 525.802363 526.402397 1368200 526.402397
2014-12-30 528.092396 531.152424 527.132366 530.422394 876300 530.422394
2014-12-29 532.192446 535.482414 530.013375 530.332426 2278500 530.332426
2014-12-26 528.772422 534.252417 527.312364 534.032454 1036000 534.032454
2014-12-24 530.512424 531.761394 527.022384 528.772422 705900 528.772422
2014-12-23 527.00237 534.56241 526.292354 530.592416 2197600 530.592416

现在,我知道这对于您的用例来说有点重,但是这样做的好处是它可以很容易地支持不同的日期格式

因为您的日期是ISO 8601,所以您可以按字典进行比较

您不需要正则表达式;只需使用awk之类的自动拆分

鉴于:

$ echo "$dates"
2014-12-31 531.252429 532.602384 525.802363 526.402397 1368200 526.402397
2014-12-30 528.092396 531.152424 527.132366 530.422394 876300 530.422394
2014-12-29 532.192446 535.482414 530.013375 530.332426 2278500 530.332426
2014-12-26 528.772422 534.252417 527.312364 534.032454 1036000 534.032454
2014-12-24 530.512424 531.761394 527.022384 528.772422 705900 528.772422
2014-12-23 527.00237 534.56241 526.292354 530.592416 2197600 530.592416
你可以做:

$ echo "$dates" | perl -lane 'print if $F[0] gt "2014-12-28" && $F[0] lt "2014-12-31"'
2014-12-30 528.092396 531.152424 527.132366 530.422394 876300 530.422394
2014-12-29 532.192446 535.482414 530.013375 530.332426 2278500 530.332426

尝试了这个,它会一遍又一遍地打印线条(就像在一个循环中)。这可能是什么原因造成的?如果有0条记录的日期较晚,如果有0条记录的日期较早,或者如果有2多条记录的日期较早,那么您的第一个解决方案就不起作用。真是浪费!字符串比较非常好。它们是按相反的顺序排序的吗?
$ echo "$dates"
2014-12-31 531.252429 532.602384 525.802363 526.402397 1368200 526.402397
2014-12-30 528.092396 531.152424 527.132366 530.422394 876300 530.422394
2014-12-29 532.192446 535.482414 530.013375 530.332426 2278500 530.332426
2014-12-26 528.772422 534.252417 527.312364 534.032454 1036000 534.032454
2014-12-24 530.512424 531.761394 527.022384 528.772422 705900 528.772422
2014-12-23 527.00237 534.56241 526.292354 530.592416 2197600 530.592416
$ echo "$dates" | perl -lane 'print if $F[0] gt "2014-12-28" && $F[0] lt "2014-12-31"'
2014-12-30 528.092396 531.152424 527.132366 530.422394 876300 530.422394
2014-12-29 532.192446 535.482414 530.013375 530.332426 2278500 530.332426