如何使 while 循环与 grep 和变量相等一起工作?

如何使 while 循环与 grep 和变量相等一起工作?

我正在尝试执行以下循环,但是失败了。我已经阅读过有关双括号和其他内容的内容,但是,我无法使其工作(尤其是与 结合的第二部分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 文件不包含短语“太多请求”,并且aequal 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的参数,本质上与关键字无关。[testif

实用程序的选项-q和会导致实用程序保持安静,并在找到匹配项后立即退出 ( ),并将给定模式视为文本字符串而不是正则表达式 ( )。-Fgrep-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$bgrepwhileif

在 中[ ... ]=测试字符串相等性和-eq测试整数相等性。从技术上讲,==它不是[ ... ]测试的有效运算符,但bash支持它。当使用 时, shell在其特殊语法bash中进行 shell 模式匹配,如下所示[[ ... ]]==

[[ $name == *.txt ]] && echo 'The name matches *.txt'

相关内容