Bash 脚本比较两个日期变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5895159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:29:10  来源:igfitidea点击:

Bash script compare two date variables

bashvariablesdatecompare

提问by Xleedos

I'm trying to compare a date given by a user to a date in a file, basically a text file with lots of dates and times listed.

我试图将用户给出的日期与文件中的日期进行比较,基本上是一个列出了大量日期和时间的文本文件。

for example the user would enter a date such as 22/08/2007 and a time of 1:00, what i need the script to do is count how many dates in the text file are after the date given by the user.

例如,用户会输入一个日期,例如 22/08/2007 和 1:00 的时间,我需要脚本做的是计算文本文件中在用户提供的日期之后有多少个日期。

I've managed to accomplish this by converting each date in the text file to unix timestamp and then comparing the two. Is there no way of simply comparing two dates in bash?

我设法通过将文本文件中的每个日期转换为 unix 时间戳,然后比较两者来实现这一点。有没有办法简单地比较 bash 中的两个日期?

Thanks in advance

提前致谢

采纳答案by ceving

The GNU date command can convert a date into the number of seconds since 1970. Try this script:

GNU date 命令可以将日期转换为自 1970 年以来的秒数。试试这个脚本:

#! /bin/bash
DATE=$(date -d "-- 01" '+%s')
COUNT=0
tr '/' ' ' | {
    while read D M Y ; do
    THIS=$(date -d "$Y-$M-$D 01" '+%s')
    if (( THIS > DATE )) ; then
        COUNT=$((COUNT + 1))
    fi
    done
    echo $COUNT
}

It expects three arguments and the raw dates in stdin:

它需要三个参数和标准输入中的原始日期:

for D in $(seq 19 25) ; do echo $D/08/2007 ; done | ./count.sh 22 08 2007
3

It will work till 2038. ;-)

它将工作到 2038 年。;-)

回答by hroptatyr

If you don't mind an external helper tool look at my dateutils. Your use case is covered by

如果您不介意外部帮助工具,请查看我的dateutils。您的用例涵盖在

dgrep -i '%d/%m/%Y %H:%M' '>=2007-08-22 01:00:00' < FILE | wc -l

where FILEis your file with the dates, and -ispecifies the date format used in the file (I assumed dates like 22/08/2007 01:00here). Matching lines will be printed, hence counting them gives you the information you were after.

FILE带有日期的文件在哪里,并-i指定文件中使用的日期格式(我假设日期像22/08/2007 01:00这里)。匹配的行将被打印出来,因此计算它们会给你你想要的信息。

回答by EdoardoSchnell

...why don't you simply cut out the single numbers, rearrange them from the most signifcant to the less significant, put them toghether to form a new big number and then compare the other one? :) Suppose you have a date in both $1and $2and suppose the date format is dd-mm-yyyy(adding hours and minutes is trivial):

...为什么不简单地剪下单个数字,将它们从最重要的到最不重要的重新排列,将它们组合在一起形成一个新的大数字,然后再比较另一个?:)假设你有在这两个日期$1$2并假设日期格式dd-mm-yyyy(添加小时和分钟是微不足道的):

d1=`echo "" | cut -d "-" -f 1`
m1=`echo "" | cut -d "-" -f 2`
y1=`echo "" | cut -d "-" -f 3`
date1="$y1$m1$d1"

d2=`echo "" | cut -d "-" -f 1`
m2=`echo "" | cut -d "-" -f 2`
y2=`echo "" | cut -d "-" -f 3`
date2="$y2$m2$d2"

if [ "$date1" -gt "$date2" ]; then
    #date1 > date2
else
    #date2 >= date1
fi

Note that you need zeros for 1-digit fields, for example, dates like this will work:

请注意,您需要为 1 位数字段设置零,例如,这样的日期将起作用:

01-01-2013

and dates like this will NOT

这样的日期不会

1-1-2013

Cheers :-)

干杯:-)

回答by Amit Pareek

the above command compares the date in form of integer and would work fine until you are comparing the dates of same year.

上面的命令以整数形式比较日期,并且在您比较同一年的日期之前可以正常工作。

better idea is to break the dates into 3 parts of dd, mm and yyyy and then do a comparison. just as below:

更好的主意是将日期分成 dd、mm 和 yyyy 的 3 个部分,然后进行比较。如下:

sysdate=date +%d%m%Ysys_dd=echo $sysdate|cut -c1,2sys_mm=echo $sysdate|cut -c3,4sys_yyyy=echo $sysdate|cut -c5-8

sysdate= date +%d%m%Ysys_dd= echo $sysdate|cut -c1,2sys_mm= echo $sysdate|cut -c3,4sys_yyyy=echo $sysdate|cut -c5-8

cd $dir_source #moving in directory where report are placed

cd $dir_source #移动到放置报告的目录中

for i in .#reading all the files present in directory and comparing with current sysdate do filename=$i filedate=echo $filename| cut -d '_' -f1file_dd=echo $filedate|cut -c1,2file_mm=echo $filedate|cut -c3,4file_yyyy=echo $filedate|cut -c5-8

因为我在#读取目录中存在的所有文件并与当前系统日期进行比较 do filename=$i filedate= echo $filename| cut -d '_' -f1file_dd= echo $filedate|cut -c1,2file_mm= echo $filedate|cut -c3,4file_yyyy=echo $filedate|cut -c5-8

if [ $sys_yyyy -lt $file_yyyy ] then echo "future cob file, check for the error"elif [ $sys_yyyy -gt $file_yyyy ] then echo "prev cob file , to be removed" else if [ $sys_mm -lt $file_mm ] then echo "future cob file, check for the error" elif [ $sys_mm -gt $file_mm ] then echo "prev cob file , to be removed" else

if [ $sys_yyyy -lt $file_yyyy ] then echo "future cob file, check for the error" elif [ $sys_yyyy -gt $file_yyyy ] then echo "prev cob file , to be removed" else if [ $sys_mm -lt $file_mm ] 然后回显“未来的 cob 文件,检查错误” elif [ $sys_mm -gt $file_mm ] 然后回显“上一个 cob 文件,要删除” else

      if [ $sys_dd -lt $file_dd ]
      then
      echo "future cob file, check for the error"
      elif [ $sys_dd -gt $file_dd ]
      then
      echo "prev cob file , to be removed"
      else
      echo "file date is same is cob date, retaining the file as it is"
      fi
 fi

fi

回答by l0b0

The problem is that dates are printed in such a way that, string-wise, "1/1/2050 1:00" < "2/1/1999 0:00". And since there's no way for a script to know that something is a datetime without you saying so, you essentially haveto convert any date to something that can be compared - Either you have to order the elements so that the most important (year) are first, etc. (like ISO dates) or you convert to a number.

问题是日期的打印方式是,按字符串,“1/1/2050 1:00”<“2/1/1999 0:00”。而且由于脚本无法在没有您说的情况下知道某事是日期时间,因此您基本上必须将任何日期转换为可以进行比较的内容 - 您必须对元素进行排序,以便最重要的(年份)是首先,等等(如 ISO 日期),或者您转换为数字。