bash
指定されたディレクトリツリー内のファイルの内容から指定された部分文字列があるかどうかを取得するスクリプトを作成しようとしています。
システムのディレクトリ(およびすべてのサブディレクトリ)を繰り返す必要があるため、再帰関数だけではgrep
不十分であり、これによりメモリ不足や中断が発生する可能性があります。したがって、スクリプトに渡されたパラメータを表す次の変数を使用して、指定されたディレクトリツリーのすべてのディレクトリとサブディレクトリのリストを取得することにしました。/
grep
find
searchdir=$HOME # passed in a script argument
searchstr="secret" # passed in a script argument
ユーティリティを呼び出し、find
出力を一時ファイルに保存します。
TF=$(mktemp)
find ${searchdir} -type d 1>$TF 2>/dev/null
while-do
一時ファイル内のすべてのディレクトリのリストを使用して各ディレクトリ内のすべてのファイルを検索するには、ループを使用してファイル行を繰り返し繰り返します。の場合grep
は、提供されたパラメータ形式を使用します。この回答隠しファイルを含む単一のディレクトリ内のすべてのファイルを検索します。
cat $TF | while read line || [[ -n $line ]];
do
grepdir="${line}/{*,.*}"
grep -sHn "${searchstr}" ${grepdir}
done
...しかし、このコードは出力を生成しません。
確認しました...
これには、${TF}
すべてのディレクトリの正しいリストが含まれています。出力${grepdir}
変数は、私が見つけると予想される出力を提供します。
/home/user/{*,.*}
/home/user/.ssh/{*,.*}
/home/user/test/{*,.*}
# ... and so on
ハードコーディングされたディレクトリ、特に2つのテストファイルと検索する文字列を含むgrep
このディレクトリでコマンドを実行する場合~/test/
grep -sHn "${searchstr}" /home/user/test/{*,.*}
...部分文字列 "secret"を含む2つのファイルを正しく出力します。
/home/user/test/asdf:7:secret
/home/user/test/test.txt:5:asdfasfdsecretaasdfafd
私に合ったフォーマットは最初再帰使用に対する回答grep
。私がこうすれば:
cat $TF | while read line || [[ -n $line ]];
do
grep -rn "${line}" -e "${searchstr}"
done
...いくつかの出力(技術的には正確ですが重複する項目が多い)を取得しましたが、grep
ディレクトリが再帰的に処理され、すべてのディレクトリのリストがあるため、同じ結果を複数回取得するしかありません。状況によっては、上記のようにルートディレクトリはgrep
完全に失敗しますします。これが私が避けようとしているものです。
また、パラメータとして渡すなど、動作させるために行ったハッキングも$(echo "${grepdir}")
結果がないという点に言及したいと思います。
私の考えや理解に誤解があるかもしれませんbash
。呼び出し前に変数を拡張しないでくださいbash
。私のスクリプトのどこで問題が発生しましたか?${grepdir}
grep
ベストアンサー1
ルール#1:コマンドまたはスクリプトが必要に応じて機能しない場合
エラーメッセージを確認してください。
それらを投げないでください /dev/null
。
次のようなエラー メッセージが表示されます。
grep: /home/user/{*,.*}: No such file or directory
grep: /home/user/.ssh/{*,.*}: No such file or directory
grep: /home/user/test/{*,.*}: No such file or directory
しかし、あなたはそれらを見ることができません。
私たちが見ると大きな打撃(1)、見よう
拡張は単語に分割され、コマンドラインから行われます。実行される拡張タイプには、中括弧拡張、チルダ拡張、パラメータおよび変数拡張、コマンド置換、算術拡張、トークン化、パス名拡張などの7種類があります。
拡張順序は、中かっこ拡張、パラメータと変数拡張、算術拡張、コマンドの置換(左から右へ)です。
あなたの場合の重要な部分は、中括弧拡張が変数拡張の前に発生することです。だからあなたが言うなら
grep -sHn "${searchstr}" "${line}"/{*,.*}
それから
- 中括弧拡張は最後のトークンをおよび
"${line}"/*
に置き換えます"${line}"/.*
。 - 変数拡張は上記の内容を次に変換し
/home/user/*
ます/home/user/.*
。 - パス名拡張は、上記の内容をファイル名のリストに変換します。
しかし、あなたが言うとき
grep -sHn "${searchstr}" ${grepdir}
それから
- 変数拡張は最後のトークンを
/home/user/{*,.*}
、
これにより、補助器の拡張が起こるのは遅すぎます。
grep
literalというファイルを見つけます/home/user/{*,.*}
。
ポリスチレン
grep -sHn "${searchstr}" "${line}/{*,.*}"
引用符は中かっこ拡張とパス名拡張が発生しないため機能しません。
調達庁:校正器はあまり必要ありません。
grep -sHn "$searchstr" "$line"/{*,.*}
それはすべてです。