【问题标题】:Passing regular expression as parameter [duplicate]将正则表达式作为参数传递[重复]
【发布时间】:2022-01-17 14:52:19
【问题描述】:

我正在尝试将正则表达式作为参数传递。我应该在我的代码中修复什么? 我的目标是发送find 和正则表达式字符串,然后在参数上使用grep,这样我就可以对grep 找到的内容做任何我想做的事情(打印出现次数)。

这是我发送的:

$ ./lab12.sh find [Gg]reen

这是我的 bash 代码:

if [[ "$1" == "find" ]]
then
    declare -i cnt=0
    for file in /tmp/beatles/*.txt ; do
        if [[ grep -e $2 ]]  //problem is here...
        then
            ((cnt=cnt+1))
        fi
    done
    echo "$cnt songs contain the pattern "$2""
fi        

【问题讨论】:

  • 方括号是 glob 语法(通配符)的一部分
  • 如果您的当前目录中有任何以Gg 开头的文件,则会产生不良结果(会发生路径名扩展)。如果不是,它不会被修改为[Gg]reen。为了产生理想的结果,单引号整个字符串
  • 此外,不匹配的模式被逐字处理只是bash默认 行为。您也可以将其配置为引发错误 (shopt -s failglob) 或消失 (shopt -s nullglob)。
  • 看看shellcheck.net。它是一个 shell 脚本验证器,还会发现可能导致您出现问题的做法。另见wizardzines.com/comics/shellcheck

标签: bash unix sh


【解决方案1】:

if 语句接受一个命令。 [[ 是一个,grep 是另一个,写 [[ grep ... ]] 本质上和写 vim grepcat grep 等一样错误,只需使用:

if grep -q -e "$pattern"
then
  ... 

改为。

-q 切换到 grep 将禁用输出,但是当模式匹配时将退出状态设置为 0(成功),否则设置为 1(失败),并且 if 语句仅在命令时执行 then 块成功了。

使用 -q 将允许 grep 在第一行匹配后立即退出。

和往常一样,请记住将参数扩展用双引号括起来,以避免pathname expansion and wordsplitting

请注意,方括号 [...] 将由您的调用 shell 解释,您应该转义它们,或者将整个模式用引号括起来。

始终建议使用单引号,因为唯一的特殊字符是另一个单引号。

$ ./lab12.sh find '[Gg]reen'

【讨论】:

  • 不只是“可以”;它被解释。问题是该模式是否产生任何匹配。
  • @chepner 我想这取决于 shell 调用程序的方式以及它的配置方式。对于所有实际问题,您都是正确的。
猜你喜欢
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多