いくつかのファイルを含むディレクトリがあります。各ファイルに特定の単語があるかどうかを知りたいです。
$1
私がパラメータとして提供したディレクトリです。
たとえば、/myscript.sh /mnt/c/User/er/Desktop/shows
このコードを書きましたが、端末に次のエラーが表示されます。[: it21754 :binary operator expected
#!/bin/bash
for a in $( find "$1" -type f )
do
if[ egrep 'it21754' $a ]
then
echo "0"
else
echo "1"
fi
done
答え1
出力を繰り返さないでくださいfind
。完全なコマンドfind
を完了して生成する必要があるため、これはややエレガントではありません。みんなループが最初の反復を実行する前の出力です。さらに、スクリプトはスペースを含むファイル名を正しく処理しません。コマンド置換の結果はスペースに分割され、ループの単語を生成します。
代わりに、find
次のようにコマンドにループのファイル名を生成させます。
find "$1" -type f -exec sh -c '...loop here...' sh {} +
私たちはすぐにこのテーマに戻ります。
ただ文法
if[ egrep 'it21754' $a ]
少し変です。egrep
ここでは必須ではありません(grep
十分です)。
「奇妙」という言葉は、テストが一般的に次の[ ... ]
ようになるか、[ op arg ]
or andなどの演算子が文字列である[ arg op arg ]
ように見えることです。拡張されるすべての項目を使用するとエラーが発生します。この条件では、実際に実行することも、実行する必要もありません。op
-f
-eq
=
arg
egrep
it21754
$a
egrep
正しいif
声明は
if grep -qwF 'it21754' "$a"; then
echo 0
else
echo 1
fi
フラグは、一致のために正規表現()の代わりに文字列比較を使用するQuiet()を-qwF
作成し、一致する文字列が部分文字列()ではなく完全な単語になることを保証します。ここでは、終了ステータスを使用して0(一致)または1(一致なし)を出力するかどうかを選択します。grep
-q
-F
-w
grep
また、ファイル名にスペースやファイル名のワイルドカードが含まれている$a
場合に備えて二重引用符を付けました。"$a"
興味深いことに、この数字はgrep
とにかく終了状態に使用されるため、プロセス全体を次のように短縮できます。
grep -qwF 'it21754' "$a"
echo "$?"
この$?
変数は、最後に実行されたコマンドの終了状態を保持します。
これをfind
コマンドにリンクすると、次のような結果が得られます。
find "$1" -type f -exec sh -c '
for a do
grep -qwF "it21754" "$a"
echo "$?"
done' sh {} +
ファイルに与えられた単語が含まれているかどうかに応じて、多くの1と0が生成されます。しかし、0または1の代わりにその単語を含むファイルのファイル名を探している可能性があると思います。この目的のために私達は利用できます
find "$1" -type f -exec grep -lwF 'it21754' {} +
ここでは(「dash ell」)-q
に変更します。これで見つかったファイルが-l
呼び出されます。grep
grep
ただ与えられた単語を含む出力ファイル名。sh -c
単一のユーティリティを呼び出すため、このビットは必要ありません。grep
そして echo
)。
もちろん、あなたも同じことができますただ grep
:
grep -R -lwF 'it21754' "$1"
を使用すると、-R
コマンドgrep
ラインで指定されたサブディレクトリを繰り返し検索します。
-w
-R
フラグは標準ではなく、grep
最も一般的なバリエーションで実装されていることに注意する価値がありますgrep
。
関連: