linux - 通过读取命令在 POSIX 兼容的 shell 脚本中解析 cal 输出

标签 linux shell unix sh posix

我正在尝试编写一个符合 POSIX 标准的脚本,它将打印指定年份的所有月份 $3 , 在 $1 中有一天(例如 Mo、Tu、...)与 $2 的日期相同(1,2,3,...).

例子: 输入:./task1.sh Tu 5 2006

输出:

September 2006
Mo Tu We Th Fr Sa Su
            1  2  3
4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30

December 2006
Mo Tu We Th Fr Sa Su
            1  2  3
4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

我写了这个脚本:

#!/bin/sh
year=$3
dayInMonth=$2
dayInWeek=$1

index=1

while expr $index '!=' 13 >/dev/null; do
  cal -m $index $year| tail -n +2| while read Mo Tu We Th Fr Sa Su ; do
    eval theDay='$'$dayInWeek
    if [ "$theDay" = "$dayInMonth" ]; then
      cal -m $index $year;
    fi
  done
  index=$(expr $index + 1)
done

但是读取第三行的cal输出有问题。在这些行中,天数通常不会从莫地方开始。我如何解析 cal 输出的第三行,以便 $Mo 中的数字, $Tu , $We ,...总是正确的?

最佳答案

更新:您已经添加了对符合 posix 的解决方案的要求。我的回答中使用的 date -d 不符合 POSIX。我会为那些使用 GNU/Linux 的人保留答案。

顺便说一句,以下命令可以正确地纠正 2006 年 1 月 5 日的星期几偏移量:

cal 01 2006 | awk -v d=5 'NR>2{for(i=1;i<NF;i++){if($i==d){print i;exit}}}'

你需要围绕它修改一些 shell 脚本。


我会使用 date 命令,如下所示:

#!/bin/bash
dayofweek="${1}"
day="${2}"
year="${3}"

for m in {01..12} ; do
    date=$(LANG=C date -d "${year}-${m}-${day}" +'%a %B')
    read d m <<< "${date}"
    [ "${d}" = "${dayofweek}" ] && echo "${m}"
done

结果:

$ bash script.sh Thu 05 2006
January
October

关于linux - 通过读取命令在 POSIX 兼容的 shell 脚本中解析 cal 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50232513/

相关文章:

performance - 在 Bash 中高效计算数十万次浮点运算

linux - 编写一个 ping 当前网络的基本脚本

c++ - gcc 错误错误的 ELF 类 : ELFCLASS64, 尽管有 -m64 标志

c - "make"编译写在 "cc ex1.c -o ex1"文件中的代码,为什么我们使用 "exe1.c"命令

bash - 从 bash 脚本发送kill -s USR1 会停止进程,而从终端执行相同操作不会停止进程

c - 在 Linux 中操作 u64 类型

c++ - 获取二进制文件的数据和代码区域的大小

linux - 用于调用主脚本的 Systemd 单元文件

php - 未创建文件 (Linux-PHP-C++)

java - 获取任何给定路径的 FileStore 对象