带表的 Shell 脚本

带表的 Shell 脚本

我想每月、每周、每天运行一个 cron 作业,但每天的小时和分钟都会发生变化,如下表所示。那么,如何使用“for 循环”来实现这一点呢?

小时和分钟将根据月份更新。

1-Apr-2022  4:59    12:41   16:13   18:56   20:26
2-Apr-2022  4:58    12:40   16:13   18:57   20:27
3-Apr-2022  4:58    12:40   16:13   18:57   20:27
4-Apr-2022  4:55    12:40   16:13   18:58   20:28
5-Apr-2022  4:54    12:40   16:14   18:59   20:29
6-Apr-2022  4:52    12:39   16:14   19:00   20:30
7-Apr-2022  4:51    12:39   16:14   19:00   20:30
8-Apr-2022  4:49    12:39   16:14   19:01   20:31
9-Apr-2022  4:48    12:38   16:14   19:02   20:32
10-Apr-2022 4:47    12:38   16:14   19:02   20:32
11-Apr-2022 4:45    12:38   16:14   19:03   20:33
12-Apr-2022 4:44    12:38   16:14   19:04   20:34
13-Apr-2022 4:42    12:37   16:14   19:04   20:34
14-Apr-2022 4:41    12:37   16:14   19:05   20:35 

答案1

这是一个简单的小型 bash 脚本,它将检查包含日期和时间的文件与问题格式相同当找到匹配项时,回显一行:

#!/bin/bash
DIR=/home/jason

CDATE=$(date +"%d-%b-%Y")
CTIME="$(echo -e "$(date +"%k:%M")" | sed -e 's/^[[:space:]]*//')"

while IFS=' ' read -r line; do
    arr=($line)

    if [ "$CDATE" = "${arr[0]}" ]; then
        echo "Found Match! ${arr[0]}"
        for (( i=1; i<=${#arr[@]}; i++)); do
            if [[ ! -z "${arr[i]}" && "$CTIME" = "${arr[i]}" ]]; then
                echo "Time to call the ${arr[i]} prayer!"
            else
                echo "$CTIME does not match ${arr[i]}."
            fi
        done
    fi
done < "$DIR/times.txt"

为了本例,我们假设将其写入名为 的文件call_prayer.sh

该脚本需要第二个名为的文件times.txt,其中包含与问题格式完全相同的日期和时间列表:

{date} {time 1} {time 2} {time 3} {time 4} {time 5} 

运行时,上述文件的输出将如下所示:

Found Match! 16-May-2022
Time to call the 5:03 prayer!
5:03 does not match 12:37.
5:03 does not match 16:14.
5:03 does not match 19:05.
5:03 does not match 20:35.
5:03 does not match .

笔记:这些祈祷时间是错误的,但没关系,因为这仅用于说明目的。

工作原理

  1. 在单独的变量中获取当前日期和时间:

    CDATE=$(date +"%d-%b-%Y")
    CTIME="$(echo -e "$(date +"%k:%M")" | sed -e 's/^[[:space:]]*//')"
    

    笔记: CTIME有一些额外的位来确保值中没有空格。使用%k会导致3,这与 不同3,因此修剪很重要。

  2. 逐行读取文件内容,并将每行拆分为一个数组:

    while IFS=' ' read -r line; do
        arr=($line)
    
  3. 将行首的日期与今天的日期进行比较。如果匹配,则继续:

    if [ "$CDATE" = "${arr[0]}" ]; then
    
  4. 循环遍历每个时间值:

    for (( i=1; i<=${#arr[@]}; i++)); do
    

    笔记:没有硬性规定每行必须有 5 个时间值。此处的代码将读取尽可能多的时间值。

  5. 将数组中的时间值与当前的{hour}:{minute}进行比较。

    if [[ ! -z "${arr[i]}" && "$CTIME" = "${arr[i]}" ]]; then
    

    笔记:其中的第一部分可能可以被删除,因为空字符串永远不会是当前时间

    1. 如果当前时间与数组时间匹配,则执行以下操作:
      echo "Time to call the ${arr[i]} prayer!"
      
    2. 如果当前时间与数组时间不匹配,则执行以下操作:
      echo "$CTIME does not match ${arr[i]}."
      
      笔记:最终代码中不需要包含这个。它只是让你知道循环现在正在运行。
  6. 完成while声明并定义包含祈祷时间的文件所在的位置:

    done < "$DIR/times.txt"
    

您可以根据自己的喜好自定义它。一定要替换文件的源目录(除非您和我使用同一个名称),并将语句替换echo为您希望在到达祈祷时间时发生的实际操作。

记得使脚本文件可执行:

sudo chmod +x call_prayer.sh

免责声明:您可以自由地以任何方式使用此代码,但是,我不保证也不会承诺继续编写免费代码。这只是为了让您入门,并希望鼓励您开发新技能。

相关内容