在 shell 脚本中执行类似 crontab 的数字匹配

发布于 2024-10-20 00:13:57 字数 273 浏览 7 评论 0原文

模拟 crontab 行前五个字段中的表达式所使用的相同数字匹配的最直接方法是什么?

例如,给定输入模式“1,5-7,16,*/3”(愚蠢的例子,我知道)和值“6”,输出将是布尔值 true。

如果没有一个非常简单的解决方案,那么在我的情况下提供第三个输入是现实的,该输入将指定星号需要匹配的最大值,以便可以翻译星号(以及连字符的范围)到值列表,并且输入值可以与该列表进行匹配。 (上面示例模式的列表将为“1,3,5,6,7,9,12,15,16,18”,最大值为“18”。)

谢谢!

What would be the most straightforward way to emulate the same numeric matching that is used for the expressions in the first five fields of a crontab line?

For example, given inputs of a pattern "1,5-7,16,*/3" (silly example, I know) and a value "6", the output would be a boolean true.

If there isn't a dead simple solution, it'd be realistic in my situation to provide a third input which would specify the maximum value that an asterisk would need to match, so that asterisks (along with the hyphenated ranges) could be translated to a list of values and the input value could be matched against that list. (The list of the example pattern above would be "1,3,5,6,7,9,12,15,16,18", given a maximum value of "18".)

Thanks!

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

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

发布评论

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

评论(1

生生漫 2024-10-27 00:13:57

我主要是一个 ksh 人,但我对 bash 的经验表明这应该有效(给出你的例子),或者至少指出你需要做什么。

hrVal=6
case ${hrVal} in   
   1|[5-7]|16 ) print -- "true" ;;
   * ) print -- "false" ;;
esac

编辑 2018-08-20 对于 bash,您需要将 print -- 更改为 echo ....< /code> 或 printf "%s\n"

实际上,我会删除 print -- "" 内容,然后调用 exit 0exit 1,然后退出适当的返回代码,然后可以由调用进程进行测试。


为了包括你的例子的其余部分,我必须

  hrVal=6
  eval "
    case ${hrVal} in

      1|[5-7]|16|$(( ${hrVal} / 3 )) ) print -- "true" ;;
      * ) print -- "false" ;;
    esac
 "

这样做所以,这可能会令人兴奋!

  • 如上所述解析 5 个时间段中的每一个,
  • 应用 sed 之类的命令将 1,5-7,16 等条目转换为 1|[5-7]|16
  • 陷阱,并将数学表达式转换为可计算表达式
    (哦,你可能可以在 case 语句之前得到结果,
    只需将值合并到....)将所有派生值保存为
    变量,
  • 使用这些变量作为案例目标​​,可能会包装整个事物并根据需要使用 eval 转义字符。
  • 评估所有 5 列返回值的组合真值(任何 false == false)

(可能是 bash 中的 (( ${hrVal} / 3 ))

IHTH

I'm mostly a ksh person, but my experience with bash says this should work (given your example), or at least point you towards what needs to be done.

hrVal=6
case ${hrVal} in   
   1|[5-7]|16 ) print -- "true" ;;
   * ) print -- "false" ;;
esac

Edit 2018-08-20 For bash, you'll need to change print -- to either echo .... or printf "%s\n".

In reality, I would remove the print -- "" stuff, and just call exit 0 or exit 1, which will then exit with the appropriate return code, that can then be tested by the calling process.


to include the rest of your example, I had to do

  hrVal=6
  eval "
    case ${hrVal} in

      1|[5-7]|16|$(( ${hrVal} / 3 )) ) print -- "true" ;;
      * ) print -- "false" ;;
    esac
 "

So, this could be exciting!

  • Parse each of 5 time bands as above
  • apply sed like commands to convert he entries like 1,5-7,16 into 1|[5-7]|16
  • trap and convert your math expressions into evaluatable expressions
    (oh, you can probably get the result before the case statement and
    just merge the value into the ....) save all derived values as
    variables,
  • use those variables as case targets, possible wrapping the whole thing and escaping chars as needed with an eval.
  • evaluate the combined truth of all 5 columns return values (any false == false)

(maybe it is (( ${hrVal} / 3 )) in bash )

IHTH

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