检查 bash 脚本命令行参数中的字符串匹配

检查 bash 脚本命令行参数中的字符串匹配

我显然缺少一些基本知识,希望能得到一些启发。我看过很多关于查看 bash 命令行参数是否与字符串匹配的帖子。但是,我无法让事情按我预期的方式运行。

这是我现在的my.script.sh

#!/bin/bash

if [[ "$*" =~  .*\.("Rmd"|"tex")$ ]]; then
    echo "Here"
else
    echo "there"
fi

我希望当任何命令行参数以“.Rmd”或“.tex”结尾时打印“Here”。但是,只有当最后的参数以“.Rmd”或“.tex”结尾。

例如

$ my.script.sh test.Rmd
Here
$ my.script.sh test.Rmd test.txt
there
$ my.script test.txt test.Rmd
Here

我尝试用“$@”代替“$*”,但无济于事。

我如何获得所需的行为(最好不使用 for 循环)?

答案1

Here仅当最后一个参数以.Rmd或结尾时才会打印.tex

因为"$*"将所有参数连接成一个字符串(例如test.Rmd test.txt),然后$在正则表达式中只能匹配此字符串

如果您的正则表达式尝试匹配空格字符作为字符串末尾的替代,那么它会起作用;但是它将无法区分单个参数和test.Rmd test.txt由单独参数产生的字符串test.Rmd,并且test.txt."$*"会给您一个不包含有关参数之间边界的确切信息的字符串。

在某些情况下可能"$*"有用,但在许多情况下这并不是您真正想要的。例如,"$*"测试“任何参数”可能会给您带来意想不到的结果,即使您想要匹配,也不一定在最后。示例:

[[ "$*" =~ "lo wo" ]]

Hello world作为参数将按预期匹配。但是(使用默认值$IFS)两个连续的参数Helloworld也将匹配;但它们都不包含lo wo

循环确实是一种完成您想做的事情的明智方法。

#!/bin/bash

message="there"
for a do
   if [[ "$a" =~ \.(Rmd|tex)$ ]]; then
      message="Here"
      break
   fi
done
echo "$message"

注意我从你的模式中删除了前导.*。一般来说,如果模式与字符串的任何部分匹配,它就会匹配;因此你需要一个明确的^(或) 来锚定到字符串的开头(或结尾);但这意味着如果你不想锚定,$你不需要前导(或尾随) (如果你打算稍后使用,你仍然可能需要)。.*.*$BASH_REMATCH

相关内容