2

残念ながら、Unix Tru64環境の制限により、GREP -rスイッチを使用して、複数のディレクトリおよびサブディレクトリにまたがるファイル内の文字列の検索を実行できません。

理想的には、2つのパラメーターを渡したいと思います。1つ目は、検索を開始するディレクトリです。2つ目は、検索するすべての文字列のリストを含むファイルです。このリストは、さまざまなディレクトリパス名で構成され、特殊文字が含まれます。

すなわち:
/ aaa / bbb / ccc
/ eee / dddd /ggggggg/
など。

この演習の目的は、リストで特定された特定のハードコードされたパス名を持つ可能性のあるすべてのシェルスクリプトを特定することです。

調査中に見つけた例が1つありましたが、これをカスタマイズして文字列引数のファイルを受け入れる方法がわかりません。

例:find etb -exec grep test {} \;

ここで、「etb」はディレクトリであり、「test」は検索対象のハードコードされた文字列です。

4

2 に答える 2

1

読んでみると、gnu coreutilが使えず、egrep が利用できないと思います。(何らかの理由で) システムが壊れており、エスケープが期待どおりに機能していないと思います。

通常の状況でgrep -rf patternfile.txt /some/dir/は、行く方法です。

検索するすべての文字列のリストを含むファイル

前提: gnu coreutil は使用できません。grep -r は機能しません。特殊文字の扱いが壊れています。

今、あなたは仕事をしていますか?番号 ?。それは人生をとても簡単にします。しかし、安全側にしましょう。

想定: 動作中sedodOR hexdumpOR xxd(vim パッケージから) のいずれかが利用可能。

これを patternfile.txt と呼びましょう


1. list を grep が好む正規表現に変換する

例 patternfile.txt の内容

/フー/

/バー/ドウ/

/根/

(例は特別な文字を出力しませんが、そこにあります。) 次のようなものに変換する必要があります。

(/foo/|/bar/doe/|/root/)

echo -enコマンドが壊れておらず、xxd、 またはod、 またはhexdumpが利用可能であると仮定すると、

16 進ダンプの使用

cat patternfile.txt |hexdump -ve '1/1 "%02x \n"' |tr -d '\n'

od の使用

cat patternfile.txt |od -A none -t x1|tr -d '\n'

それをパイプして(hexdumpとodの両方に共通) |sed 's:[ ]*0a[ ]*$::g'|sed 's: 0a:\\|:g' |sed 's:^[ ]*::g'|sed 's:^: :g' |sed 's: :\\x:g' 、次に結果をパイプする |sed 's:^:\\(:g' |sed 's:$:\\):g' と、エスケープされた正規表現パターンが得られます。


2.エスケープされたパターンを壊れた正規表現にフィードします

最小限のシェル エスケープが利用可能であると仮定して、これを使用grep "$(echo -en "ESCAPED_PATTERN" )"して作業を行います。


3. まとめると

エスケープされた正規表現パターンの構築 (例として hexdump を使用)

grep "$(echo -en "$( cat patternfile.txt |hexdump -ve '1/1 "%02x \n"' |tr -d '\n' |sed 's:[ ]*0a[ ]*$::g'|sed 's: 0a:\\|:g' |sed 's:^[ ]*::g'|sed 's:^: :g' |sed 's: :\\x:g'|sed 's:^:\\(:g' |sed 's:$:\\):g')")"

すべての文字をエスケープし、(|) 括弧で囲むので、正規表現 OR 一致が実行されます。

4.再帰的なディレクトリ検索

通常の状況では、grep -rが壊れていても動作するfind /dir/ -exec grep {} \;はずです。xargsinstaedを好む人もいるかもしれません (バグのある xargs を持っていない限り)。私たちはアプローチを好みfind /somedir/ -type f -print0 |xargs -0 grep -f 'patternfile.txt'ますが、これは (正当な理由で) 利用できないためgrep、ファイルごとに exec する必要があり、これは通常間違った方法です。でもやってみよう。

仮定:find -type f動作します。想定:xargsが壊れているか、利用できない。

まず、バグのあるパイプを使用している場合、多数のファイルを処理できない可能性があります。したがってxargs、そのようなシステムでは避けます(わかっています、わかっています、壊れているふりをしましょう)。

find /whatever/dir/to/start/looking/ -type f > list-of-all-file-to-search-for.txt

シェルが大きなサイズのリストを適切に処理できる場合は、それ for file in cat list-of-all-file-to-search-for.txt ; do grep REGEXP_PATTERN "$file" ; done ; がうまくいく方法です。残念ながら、一部のシステムはそれを好まず、その場合、 cat list-of-all-file-to-search-for.txt | split --help -a 4 -d -l 2000 file-smaller-chunk.part. それをより小さなチャンクに変換する必要がある場合があります。今、これは深刻な壊れたシステムのためのものです。その後、動作するfor file in file-smaller-chunk.part.* ; do for single_line in cat "$file" ; do grep REGEXP_PATTERN "$single_line" ; done ; done ; はずです。

cat filelist.txt |while read file ; do grep REGEXP_PATTERN $file ; done ; 一部のシステムでは、回避策としてA を使用できます。

シェルが引用符を処理しない場合はどうなりますか?

事前にファイル リストをエスケープする必要がある場合があります。

awk、 、何であれ、それははるかにうまく行うことができますが、perl私たちは自分自身を に制限しているので、それを sedしましょう. 0x27, the ' code 実際に動作 すると仮定します。cat list-of-all-file-to-search-for.txt |sed 's@['\'']@'\''\\'\'\''@g'|sed 's:^:'\'':g'|sed 's:$:'\'':g' これを使用しなければならなかったのは、出力を bash に再度供給するときだけでした。

私のシェルがそれを処理しない場合はどうなりますか?

xargs失敗、grep -r失敗、シェルの for ループの失敗。

他に何かありますか?はい。

シェルに適したすべての入力をエスケープし、スクリプトを作成します。

しかし、ご存知のように、私はボードを手に入れました.cshの自動化されたスクリプトを書くのは間違っているようです. ですから、ここでやめます。

お持ち帰りメモ

適切な仕事のためにツールを使用してください。インタプリタを書くbcことは完全に可能ですが、それは明らかに間違っています。coreutils をインストールperlしてgrep ください。人生をより良いものにします。

于 2010-11-04T12:35:41.543 に答える
1

これはそれを行う必要があります:

find dir -type f -exec grep -F -f strings.txt {} \;

dir検索を開始するディレクトリです

strings.txt1 行に 1 つずつ、照合する文字列のファイルです

-F検索文字列を正規表現ではなくリテラルとして扱うことを意味します

-f strings.txtstrings.txtマッチングに文字列を使用することを意味します

-l一致するファイル名だけが必要な場合は、grep スイッチに追加できます。

脚注:

を含むソリューションを好む人もいますxargs

find dir -type f -print0 | xargs -0 grep -F -f strings.txt

場合によっては、おそらくもう少し堅牢で効率的です。

于 2010-11-04T09:58:41.243 に答える