【问题标题】:Check the last saturday of the current month检查当月的最后一个星期六
【发布时间】:2021-02-19 06:14:54
【问题描述】:

我正在尝试运行一个 shell 脚本来检查今天是否是当月的最后一个星期六,然后它会运行一些脚本。例如,28 日是本月的最后一个星期六。 这是我正在尝试的代码:

#!/bin/bash
DoDay=$(ncal -h | awk ' /Su/ {print $(NF-1)}')
Date=(date +%d)

if [[$Date == $DoDay]]
then 
    echo "Last Saturday"
else 
    echo "not last"
fi

执行时显示为:

ncal:command not found.

有人可以帮忙吗? 提前致谢

【问题讨论】:

  • 在某些 BSD 系统上,可以使用 date -v1d -v+1m -v-1d -v-sat 来获取该月的最后一个星期六。
  • 你在Date=(date +%d)中少了一个$

标签: shell unix awk


【解决方案1】:

请您尝试以下操作。我将它作为命令运行,您可以将其保存在脚本中,也可以从 cron 运行它以每天检查它。

cal $(date +%m) $(date +%Y) | 
tac | 
awk -v date=$(date +%d) '
  count==1{  exit  }
  NF==7{
    ++count
    if($(NF-1)==date){
      print "Today is last Saturday of month."
      exit
    }
    else{
      print "Today is NOT last Saturday of month."
    }
}'

对于今天的日期(今天是 2020 年 11 月 6 日的星期五),输出如下。

Today is NOT last Saturday of month.

说明:为上述添加详细说明。

cal $(date +%m) $(date +%Y) |                       ##Running cal command with passing current month and today date to it
tac |                                               ##Passing cal output to tac command to print it from bottom to top, since we want to read last lines only.
awk -v date=$(date +%d) '                           ##Passing previous output to awk as an Input and create date variable which has today date in it.
  count==1{  exit  }                                ##If count variable is 1 thne exiting from program.
  NF==7{                                            ##Checking condition if number of fields is 7 then do following.
    ++count                                         ##Increasing count with 1 here.
    if($(NF-1)==date){                              ##Checking condition if last field is date then do following.
      print "Today is last Saturday of month."      ##Printing that its last Saturday for this month.
      exit                                          ##exiting from program from here.
    }
    else{                                           ##Else part of above if condition here.
      print "Today is NOT last Saturday of month."  ##printing that its NOT last Saturday of this month.
    }
}'

【讨论】:

    【解决方案2】:

    如果您使用的是 GNU AWK,您可以利用它的 time functions。我会通过以下方式检查:

    BEGIN{nowtime=systime();nowweekday=strftime("%u",nowtime);nowmonth=strftime("%m",nowtime);nextmonth=strftime("%m",nowtime+604800);if(nowweekday==6 && nowmonth!=nextmonth){print "Last saturday of month"}else{print "Not last saturday of month"}}
    

    解释:首先我得到当前时间,以从纪元开始以来的秒数为单位,然后我得到当前工作日作为数字(1-星期一,7-星期日),当前月份作为数字(1-12)和日期月份 7天后(604800 是 7 天的秒数)。如果今天是星期六,7 天后将是不同的月份,这是最后一个星期六,否则不是,我会相应地打印出来

    【讨论】:

    • 好主意,但是您应该使用 noon today 来获取今天(现在)的纪元以来的秒数,而不是今天的当前实际时间,这样当您在一周后添加典型的秒数时如果当前时间(或 1 周后的等效时间)在受 DST 转换影响的一小时内,您不会得到错误的结果,因为这可能会使您的“+ 1 周”计算在周五或周日结束,而不是每周的周六稍后。
    • 请添加一些空格,以便您的代码可读。
    • @EdMorton:我必须承认我没有考虑到这种极端情况
    【解决方案3】:

    获得当月最后一个星期六的一些替代方法:

    • ncal

      $ ncal | awk '$1 == "Sa" {print $NF}'
      28
      
    • 卡尔

      $ cal | awk 'NF == 7 {day = $7} END {print day}'
      28
      
    • 带有一些 shell 算法的 GNU 日期:这使用嵌套的日期调用来获取本月最后一天的星期几和星期几,然后向后迭代直到星期几是星期六。

      $ read day dow < <(date -d "$(date  '+%Y-%m-01 +1 month -1 day')" '+%d %w')
      $ while ((dow != 6)); do ((day--)); ((dow = (dow - 1 + 7) % 7)); done
      $ echo $day
      28
      

    【讨论】:

      【解决方案4】:

      GNU date 具有一些文本解析功能,可以简化这一点:

      if test `date +%w` -eq 6 && test "$(date +%m)" -ne "$(date -d 'next saturday' +%m)"; then
          echo "Last Saturday"
      else
          echo "not last"
      fi
      

      【讨论】:

      • 感谢您的回复。你能告诉我这里的测试表明什么吗?
      • test 是一个实用程序二进制文件和/或 shell 内部,它进行比较并返回真/假返回值
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 1970-01-01
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多