grepと変数の同等性を使用してwhileループを操作するには?

grepと変数の同等性を使用してwhileループを操作するには?

次のループを実行しようとして失敗します。二重括弧やその他の内容について読みましたが、動作させることはできません(特に共用体の2番目の部分ではgrep)。各部分を個別に動作させることはできますが、2つの部分を一緒に操作することはできません。

最初の試み:

a=1;
b=1;

while { ( n1=$(grep 'too many requests' *.htm* )) && (( $a -eq $b  )) }; do
    echo "aa"
done
    

2回目の試み:

while [[  n=$(grep 'too many requests' *.htm* ) && $a==$b ]]; do
    echo "error"
done

3回目の試み

while [[  n=$(grep 'too many requests' *.htm* ) &&  "$a" -eq "$b"  ]]; do
    echo "aa"
done

a私の予想は次のとおりです。 HTMLファイルに「要求が多すぎる」というフレーズが含まれていない場合は、bループを入力します。

ベストアンサー1

a=1
b=1

if ! grep -q -F -- 'too many requests' *.htm* && [ "$a" = "$b" ]; then
    echo error >&2
fi

これは負の終了状態grepと比較合計の結果を使用して文字列の同一性を$a表します$b(整数の同一性の評価には['を使用します)。-eq両方とも本物(文字列は一致するファイルに見つからず、*.htm*両方の変数は同じです。)echoその後、文字列が実行され、error標準エラーストリームに文字列が出力されます。

シングルを使用し=てその周囲にスペースを追加することに注意してください。=(または)演算子は-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[(( ... ))

2番目のコードスニペットではを使用します。これは、シェルがコマンドとして使用しようとする$a==$b文字列として評価されます。1==1

3番目のコードスニペットでは、との間の整数同一性テストを"$a" -eq "$b"正しく実行するinsideを使用します。[[ ... ]]コマンドと終了ステータスを否定しない方法(およびステートメントの代わりにループを使用しているという事実)のため、これは期待どおりに機能しません。$a$bgrepwhileif

では、文字列の同一性[ ... ]=テストし、-eq整数の同一性をテストします。技術的にはテストに有効な演算子で==はありませんが、サポートされています。使用すると、シェルは以下のように特殊な構文でシェルパターンマッチングを実行します。[ ... ]bashbash[[ ... ]]==

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

おすすめ記事