Как я могу разобрать вывод cal в sh командой read? - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь написать скрипт, который будет печатать все месяцы в указанном году $3, у которых день в $1 (например, Мо, Ту, ...) совпадает с датой $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, чтобы числа в $Mo, $Tu, $We, ... всегда были правильными?

Мне нужно стандартное дружественное решение POSIX.

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Проверять даты проще с помощью команды date.

for month in {1..12}; do 
  if [[ $(date -d $(printf "%s-%2.2d-%2.2d" "$year" "$month" "$day") "+%a") == "Tue" ]]; then 
    cal -m $month $year; 
  fi
done

Скрипт зацикливается на 12 месяцев и генерирует дату на основе года и дня. Команда date выводит день в 3-буквенном формате с +%a.

Если вы хотите указать день недели в числовом формате, используйте +%u и == 2 в выражении if.

0 голосов
/ 08 мая 2018

Обновление: вы добавили требование для решения, соответствующего posix.date -d в моем ответе не соответствует POSIX.Я сохраню ответ для тех, кто использует GNU / Linux.

Кстати, следующая команда дает вам правильное смещение дня недели от 5 января 2006 года:

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

Вам нужно повозиться с небольшим сценарием оболочки.


Я бы использовал команду 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
...