我有一個問題,我想過濾檔案中超過 18 個月的內容。
檔案如下所示:
> cat trans_file.txt
trans-02-2018
trans-03-2019
trans-04-2021
trans-01-2022
需要的輸出:
trans-02-2018
trans-03-2019
我正在使用以下方法:
export DT=`date %m-%Y`
export DTLastYear=`date %m-%Y -d '18 months ago'`
perl -ne 'print if grep {$_<$ENV{$DTLastYear}} /(\d{2}-\d{4})/g' trans_file.txt
但它不起作用。有人可以在這里幫忙嗎?
uj5u.com熱心網友回復:
我會在 pureperl中使用核心時間處理模塊而不是date(1)獲取 18 個月前的日期(并從行中決議日期而不是使用正則運算式):
作為一個單行:
$ perl -MTime::Piece -MTime::Seconds -lne '
BEGIN { $when = localtime() - (ONE_MONTH * 18) }
my $t = Time::Piece->strptime($_, "trans-%m-%Y");
print if defined $t && $t < $when;' trans_file.txt
trans-02-2018
trans-03-2019
或者作為一個單獨的腳本,將輸入檔案名作為命令列引數,或者如果沒有,則從標準輸入讀取:
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use v5.22.0; # For <<>>; use the less-secure <> on older perls
use Time::Piece;
use Time::Seconds;
my $when = localtime() - (ONE_MONTH * 18);
while (my $line = <<>>) {
chomp $line;
my $t = Time::Piece->strptime($line, "trans-%m-%Y");
say $line if defined $t && $t < $when;
}
或者使用zdim 提到的非核心但經常有用的DateTime模塊:
#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
use v5.22.0; # For <<>>; use the less-secure <> on older perls
use DateTime; # Install through your OS package manager or favorite CPAN client
my $when = DateTime->now->truncate(to => 'month')->subtract(months => 18);
while (my $line = <<>>) {
chomp $line;
if ($line =~ /(\d\d)-(\d{4})$/) {
my $t = DateTime->new(month => $1, year => $2);
say $line if $t < $when;
}
}
你哪里出錯了
All of the above convert times to objects that can be compared, instead of using strings like your attempt (Though in perl you need lt instead of < to compare strings). It can also be done that way, but you have to use a date format that can be meaningfully compared as strings. You're trying to use a 'MM-YYYY' format , but that doesn't sort properly - 01-2020 comes before 12-2019, for example, because 0 is before 1. If you switch it around to a 'YYYY-MM' format, you can make it work using string comparison.
bash example:
dt_last_year=$(date %Y-%m -d '18 months ago')
while read -r line; do
if [[ $line =~ ([0-9][0-9])-([0-9]{4})$ ]]; then
# date in YYYY-MM format
t="${BASH_REMATCH[2]}-${BASH_REMATCH[1]}"
if [[ $t < $dt_last_year ]]; then
printf "%s\n" "$line"
fi
fi
done < trans_file.txt
uj5u.com熱心網友回復:
與bash:
x=$(date %Y-%m -d '18 months ago')
while IFS='-' read -r prefix month year; do
[[ "$year-$month" < "$x" ]] && echo "$prefix-$month-$year";
done < file
輸出:
trans-02-2018 trans-03-2019
uj5u.com熱心網友回復:
<用于數值比較。您需要lt用于字串比較。
您需要重新排序年份和月份才能使用字串比較。
你想要字串DTLastYear,而不是變數$DTLastYear。
固定的:
export DTLastYear=`date %Y-%m -d '18 months ago'`
perl -ne'/(\d{2})-(\d{4})/ or next; print if "$2-$1" lt $ENV{DTLastYear}' trans_file.txt
簡化:
export DTLastYear=`date %Y-%m -d '18 months ago'`
perl -F- -lane'print if "$F[2]-$F[1]" lt $ENV{DTLastYear}' trans_file.txt
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425531.html
上一篇:Perl浮點有什么域?
下一篇:匹配一個浮點數并乘以100
