
次のループを実行しようとして失敗します。二重括弧やその他の内容について読みましたが、動作させることはできません(特に共用体の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
()ユーティリティの引数であり、デフォルトではキーワードに依存しません。[
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
[
(( ... ))
2番目のコードスニペットではを使用します。これは、シェルがコマンドとして使用しようとする$a==$b
文字列として評価されます。1==1
3番目のコードスニペットでは、との間の整数同一性テストを"$a" -eq "$b"
正しく実行するinsideを使用します。[[ ... ]]
コマンドと終了ステータスを否定しない方法(およびステートメントの代わりにループを使用しているという事実)のため、これは期待どおりに機能しません。$a
$b
grep
while
if
では、文字列の同一性[ ... ]
を=
テストし、-eq
整数の同一性をテストします。技術的にはテストに有効な演算子で==
はありませんが、サポートされています。使用すると、シェルは以下のように特殊な構文でシェルパターンマッチングを実行します。[ ... ]
bash
bash
[[ ... ]]
==
[[ $name == *.txt ]] && echo 'The name matches *.txt'