linux - 如何在循环的 bash 脚本中引用 "next"命令行参数?

标签 linux bash shell unix

我正在编写一个简单的 bash 脚本,该脚本使用 if 和 else 语句通过 cal 命令打印出日历。

这是我的代码:

  #!/bin/sh

  for f in $*
  do
      #if input $f is a number use it
      if [ $f -eq $f ]; then
          cal $f
      #if it's not a number then print cal and assume there's a year right after it ($2)
      else
          cal $f $2
      fi
  done

这类作品。如果我执行“./mycal 2008”,它会毫无怨言地打印出 2008 年。但是,如果我执行“./mycal june 2008”,我希望它只打印出 2008 年 6 月这个月。

虽然我的 for 循环设置不正确。发生的事情是

  1. mycal 打印出 2008 年 6 月

  2. mycal 打印出 2008 年全年。

这是因为我的 for 循环 - 在打印 2008 年 6 月之后,它转到下一个命令行输入,即 2008(一个数字),所以它打印 2008 年一整年。

有什么办法可以避免这种情况吗?一旦任一条件评估为真,我可能会中断或退出程序,但我希望能够做类似的事情

./mycal 2007 年 6 月 2005 年 3 月 2022 年 9 月

  1. 2007 年 6 月打印
  2. 2005 年 3 月打印
  3. 2022 年 9 月打印

使用像 C 这样的语言,我可能会做这样的事情。

for (x=0; x< length(argArray); x++)
{
    //argArray[x] is a string like "june" or something
    if (isNotInt(argArray[x]))
    {
        //cal month + year
        cal ( argArray[x], argArray[x+1] );
        x++; //move to the next arg, skip x+1 because it's a year we just used
    }  
    //argArray[x] is a number, print it.
    else
    {
        cal ( argArray[x] );
    }
}

有什么想法吗?如果我可以在 shell 脚本中访问具有数组索引的项目,那就太好了。我是 sh 脚本的新手,感谢您的帮助!

最佳答案

我会使用 while 循环来遍历参数列表,并根据需要进行移动。查看第一个参数,如果是一年,我们就立即调用 cal。否则,我们看下一个参数。如果 是一年,我们调用带有两个参数的调用,否则只使用当前参数。

while [ "$#" -gt 0 ]; do
    month_or_year=$1
    shift
    # bash only: if [[ $month_or_year =~ [0-9]+ ]]; then
    if expr "$month_or_year" : '[0-9][0-9]*' > /dev/null; then
        # Just a year
        cal "$month_or_year"
    # bash only: if (( $# )) && [[ $month_or_year =~ [0-9]+ ]]; then
    elif [ "$#" -gt 0 ] && expr "$1" : '[0-9][0-9]*' > /dev/null; then
        # A month and a year
        month=$month_or_year
        year=$1
        shift
        cal "$month" "$year"
    else
       # Just a month
        cal "$month_or_year"
    fi
done

根据您的 cal 的实际版本,您可能需要将月份转换为数字。我会使用像这样的案例陈述

case $month in
    jan|January) month=1 ;;
    feb) month=2 ;;
    mar) month=3 ;;
    apr) month=4 ;;
    may) month=5 ;;
    jun) month=6 ;;
    jul) month=7 ;;
    aug) month=8 ;;
    sep) month=9 ;;
    oct) month=10 ;;
    nov) month=11 ;;
    dec) month=12 ;;
    *) printf 'Unrecognized month: %s\n' "$month_or_year"; exit 1 ;;
esac

调整您要接受的参数的大小写。标签区分大小写,January 提供了一个接受月份替代名称的示例。

关于linux - 如何在循环的 bash 脚本中引用 "next"命令行参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33878780/

相关文章:

bash - 此处文档给出 'unexpected end of file' 错误

linux - 如何删除//当前文件夹和子文件夹中所有文件的注释行?

php - 在 Linux 中使用 PHP/Shell 脚本从浏览器重启 MySql 服务器

linux - 将重复值重定向到新文件

linux - Shell 中的 Perl 编程

linux - 参数扩展

bash - bash 中 $x, $[x], ${x} 的区别

linux - 如何安装 oracle-rdbms-server-11gR2-preinstall

linux - 关闭源校验和检查 Yocto

linux - 在bash中修改用户