我正在尝试执行以下循环,但是失败了。我已经阅读过有关双括号和其他内容的内容,但是,我无法使其工作(尤其是与 结合的第二部分grep
)。我可以让每个部分单独工作,但不能让两个部分一起工作。
第一次尝试:
a=1;
b=1;
while { ( n1=$(grep 'too many requests' *.htm* )) && (( $a -eq $b )) }; do
echo "aa"
done
第二次尝试:
while [[ n=$(grep 'too many requests' *.htm* ) && $a==$b ]]; do
echo "error"
done
第三次尝试
while [[ n=$(grep 'too many requests' *.htm* ) && "$a" -eq "$b" ]]; do
echo "aa"
done
我的期望是:如果 HTML 文件不包含短语“太多请求”,并且a
equal b
,则进入循环。
答案1
a=1
b=1
if ! grep -q -F -- 'too many requests' *.htm* && [ "$a" = "$b" ]; then
echo error >&2
fi
这使用 的否定退出状态grep
和 比较 和 的结果来$a
表示$b
字符串相等性(使用[
's-eq
进行相等性的整数评估)。如果两者都是真的(在任何文件匹配中都没有找到该字符串*.htm*
,并且两个变量相同),然后echo
执行该字符串,将该字符串输出error
到标准错误流。
请注意使用 single=
并在其周围添加空格。=
(or ) 运算符是( ) 实用程序-eq
的参数,本质上与关键字无关。[
test
if
实用程序的选项-q
和会导致实用程序保持安静,并在找到匹配项后立即退出 ( ),并将给定模式视为文本字符串而不是正则表达式 ( )。-F
grep
-q
-F
您的示例使用while
循环,它应该是一个if
语句。如果要单独处理每个文件,请使用循环for
:
for name in *.htm*; do
if ! grep -q -F -- 'too many requests' "$name" && [ "$a" = "$b" ]
then
printf 'error for "%s"\n' "$name" >&2
fi
done
grep
如果您只想测试某个模式是否在一个文件或一组文件中匹配,则不必保存输出。您可以改为使用grep -q
实用程序的退出状态并对其做出反应,如上所示。
在您的第一个代码片段中,您使用算术评估,(( $a -eq $b ))
.这可以更好地写为,它计算出一个语句可以用作布尔值(( a == b ))
的结果。if
该-eq
运算符特定于[
实用程序,在 中无效(( ... ))
。
在第二个代码片段中,您使用$a==$b
.这将计算为一个字符串1==1
,shell 将尝试将其用作命令。
在第三个代码片段中,您使用"$a" -eq "$b"
inside ,它可以正确执行和[[ ... ]]
之间的整数相等性测试。由于命令和您不否定其退出状态的方式(以及您使用循环而不是语句的事实),这不能按预期工作。$a
$b
grep
while
if
在 中[ ... ]
,=
测试字符串相等性和-eq
测试整数相等性。从技术上讲,==
它不是[ ... ]
测试的有效运算符,但bash
支持它。当使用 时, shell在其特殊语法bash
中进行 shell 模式匹配,如下所示[[ ... ]]
==
[[ $name == *.txt ]] && echo 'The name matches *.txt'