linux shell中日历编程问题

发布于 2024-12-18 16:05:51 字数 745 浏览 0 评论 0原文

我希望我的日历能够正确处理带有前导零的月份 例如:“cal 01”或“cal 01 2012”

如何编写代码以使我的日历正确处理带有前导零的月份?

到目前为止,这是我的代码:

$ cat cal
#cal: nicer interface to /usr/bin/cal

case $# in
0)  set 'data';m=$2; y=$6 ;;    # no argu: use today
1)  m=$1; set 'data'; y=$6 ;;   # 1 rg: use this year
*)  m=$1; y=$2 ;;           # 2 ags: month and year 
esac

case $m in
jan*|Jan*)  m=1 ;;
feb*|Feb*)  m=2 ;;
mar*|Mar*)  m=3 ;;
apr*|Apr*)  m=4 ;;
may*|May*)  m=5 ;;
jun*|Jun*)  m=6 ;;
jul*|Jul*)  m=7 ;;
aug*|Aug*)  m=8 ;;
sep*|Sep*)  m=9 ;;
oct*|Oct*)  m=10 ;;
nov*|Nov*)  m=11 ;;
dec*|Dec*)  m=12 ;;
[1-9]|10|11|12) ;;          # numeric month
*)      y=$m; m="" ;;       # plain year
esac

/usr/bin/cal $m $y          # run the real one
$

I want my calendar to correctly handle months with leading zeros
for example: "cal 01" or "cal 01 2012"

How do I write the code to make my calendar to correctly handle months with leading zeros?

This is my code so far:

$ cat cal
#cal: nicer interface to /usr/bin/cal

case $# in
0)  set 'data';m=$2; y=$6 ;;    # no argu: use today
1)  m=$1; set 'data'; y=$6 ;;   # 1 rg: use this year
*)  m=$1; y=$2 ;;           # 2 ags: month and year 
esac

case $m in
jan*|Jan*)  m=1 ;;
feb*|Feb*)  m=2 ;;
mar*|Mar*)  m=3 ;;
apr*|Apr*)  m=4 ;;
may*|May*)  m=5 ;;
jun*|Jun*)  m=6 ;;
jul*|Jul*)  m=7 ;;
aug*|Aug*)  m=8 ;;
sep*|Sep*)  m=9 ;;
oct*|Oct*)  m=10 ;;
nov*|Nov*)  m=11 ;;
dec*|Dec*)  m=12 ;;
[1-9]|10|11|12) ;;          # numeric month
*)      y=$m; m="" ;;       # plain year
esac

/usr/bin/cal $m $y          # run the real one
$

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

婴鹅 2024-12-25 16:05:51

您可以在 case 语句中进行多个正则表达式匹配,即

case $m in
01|1|jan*|Jan*)  m=1 ;;
02|2|feb*|Feb*)  m=2 ;;

....

否则,您可以使用 shell 参数替换来删除任何前导 0,即

# as a way to demonstrate param sub on $1 etc, load values to $1 and $2
set -- 01 02 
echo ${1#0}
echo ${2#0}

# output
1
2

编辑

对于您的后续问题

例如,当前月份是 2005 年 11 月,如果运行“cal 01”,则应该打印出 2006 年 1 月的日历

试试这个:

# if the month input is less than the current month, assume the next year
if (( ${y:-0} == 0  && m < $(/bin/date +%m) )) ; then
   y=$(/bin/date +%Y)
   ((y++))
fi

${y:-0} 是几个参数之一检查大多数 shell 提供的语法,如果 var 值完全未设置(根本没有设置)或 = "",则允许替换默认值。因此,在这种情况下,如果 y 未由命令行设置,则在此评估中它将显示为 0,从而允许执行 && 部分测试月份等。

您需要扩展 case $# 处理以允许 1 个参数,该参数被假定为月份值。

我希望这有帮助。

You can do multiple regex matching in your case statement, i.e.

case $m in
01|1|jan*|Jan*)  m=1 ;;
02|2|feb*|Feb*)  m=2 ;;

....

Else, you could use shell parameter substitution to remove any leading 0's, i.e.

# as a way to demonstrate param sub on $1 etc, load values to $1 and $2
set -- 01 02 
echo ${1#0}
echo ${2#0}

# output
1
2

Edit

For your follow-up question

Example, the current month is November, 2005, if you run "cal 01", you should print out the calendar of Jan. 2006

Try this:

# if the month input is less than the current month, assume the next year
if (( ${y:-0} == 0  && m < $(/bin/date +%m) )) ; then
   y=$(/bin/date +%Y)
   ((y++))
fi

${y:-0} is one of several parameter checking syntaxs provided by most shells that allows a default value to be substituted if the var value is completely unset (not set at all) or = "". So in this case, if y wasn't set by the command line, it will appear as 0 in this evaluation, allowing the && section to be be executed to test the month, etc.

You'll need to extend your case $# processing to allow for 1 argument, that is assumed to be a month value.

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文