正则表达式检查命令参数

正则表达式检查命令参数

我想用来检查运行的grep命令是否包含该单词作为参数。 (我知道 Bash 中的有关,我不想使用它)。cmdname!*

假设我有一个名为 的变量中的命令process

起初我尝试过echo $process | grep 'cmd name'。这还不够完善,因为它只考虑了一个参数。

所以我尝试看看是否可以使用 regex 将其捕获为最后一个参数cmd .*(?= )name。这个想法是捕获任何内容,然后是一个空格,然后是name(after cmd)。但这行不通。

如果这有效的话,我的目标是尝试将其解释为任何立场的争论。

如何使用正则表达式来做到这一点?

答案1

在下面的答案中,我明确避免使用grep.命令行是一个单独项目的列表,它应该被解析为这样,而不是作为一行文本。


假设您将命令和命令的参数都保存在单个字符串中(最好使用数组,请参阅我们如何运行存储在变量中的命令?),那么你可以做类似的事情

process='cmd with "some arguments" and maybe name'

set -f
set -- $process

if [ "$1" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

shift

for arg do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

这将首先禁用文件名生成,因为我们想要使用$process不带引号的将其分割成单独的单词,并且如果该字符串包含文件名通配模式(如*),它会扰乱我们对其的解析。我们用 来做到这一点set -f

然后我们将位置参数设置为 中的单词$process。之后,如果"$1"是,我们知道我们应该在命令行的其余部分中cmd查找。name如果没有,我们就到此为止。

我们shift离开cmd位置参数列表并开始循环查看参数。在每次迭代中,我们只需将参数与字符串进行比较name。如果我们找到它,我们就会说出来并退出。

在循环结束时,我们知道我们还没有找到参数name,因此我们报告这一点并失败退出。

请注意,在上面的示例中,参数some arguments将被解析为两个分离strings"somearguments",这是您永远不想将命令及其参数存储在单个字符串中的原因之一。这也意味着它将检测name单个参数内的参数"some name string",这将是误报。


如果命令行存储在数组中(例如bash),那么您可以这样做:

process=( cmd with "some arguments" and maybe name )

if [ "${process[0]}" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

for arg in "${process[@]:1}"; do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

的扩展"${process[@]:1}"将是整个数组,但不是第一项(命令名称)。

对于/bin/sh(and dash,但也bash包括任何其他 POSIX shell),上面的内容就不那么啰嗦了:

set -- cmd with "some arguments" and maybe name

if [ "$1" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

shift

for arg do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

这本质上与第一段代码相同,但正确处理所有参数(引用等),因为我们从不将命令行的所有元素组合成单个文本字符串。

答案2

既然你提到了 bash,另一个选择是它的模式匹配运算符=~

if [[ $process =~ ^cmd[[:space:]].*name([[:space:]]|$) ]]
then
  _name_ was found as an argument to _cmd_
fi

这会查看变量的内容是否以 开头cmd,后跟空格,后跟任何内容或无内容,后跟name,后跟:空格或行尾。

相关内容