我想用来检查运行的grep
命令是否包含该单词作为参数。 (我知道 Bash 中的有关,我不想使用它)。cmd
name
!*
假设我有一个名为 的变量中的命令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"some
和arguments"
,这是您永远不想将命令及其参数存储在单个字符串中的原因之一。这也意味着它将检测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
,后跟:空格或行尾。