web-dev-qa-db-ja.com

ファイルシステム全体で文字列を含むファイルを検索する

ファイルシステム全体で特定の文字列のすべてのインスタンスを見つける必要があります。これは、どの構成ファイル、スクリプト、またはその他のプログラムに配置したかを覚えておらず、その文字列を新しい文字列で更新する必要があるためです。

次のコマンドで試してみました

`grep -nr'needle '/ --exclude-dir = .svn | mail [email protected] -s'xxxに関する参照 '

このコマンドを小さなディレクトリで実行すると、必要な出力が次の形式で表示されます。

/path1/:nn:line containing needle
/path2/:nn:line containing needle

ここで、/ path1はファイルのフルパス、nnは針を含む行、最後のフィールドは行の内容です。

ただし、ルートディレクトリでコマンドを実行すると、しばらくするとgrepプロセスがハングします。このスクリプトを約8時間前に実行しましたが、小さなファイルシステム(5GB未満)でも終了せず、topまたはpsを実行するとプロセスがスリープしているように見えます

root 24909 0.0 0.1 3772 1520 pts/1 S+ Feb10 0:15 grep -nr needle / --exclude-dir=.svn

なぜ終わらないのですか?これを行うためのより良い方法はありますか(これは1回限りのジョブであり、これを複数回実行する必要はありません)

ありがとう。

更新:findとxargsを使用して機能しているソリューションを見つけました。これは機能しているようで、find-execソリューションよりもシステムリソースの使用量が少なくなっています。これが私の最後のコマンドラインです:

find /{boot,etc,home,lib,lost+found,opt,root,sbin,usr,var} -type f -print0 | xargs -r0 grep -nr 'needle' | mail [email protected] -s 'References on xxx'

/{dir1,dir2,...,dirn}構文を使用したのは、先頭のスラッシュを含むフルパスを含む出力行が必要なためです。このようにして、cd /なしで、つまり任意のディレクトリからコマンドを使用できます。

2
Fabio

ファイルシステムには、実際のファイルではなく、カーネルへのフックであるファイルがいくつかあります。それらのいくつかは永遠に読むことができます。試してみてください

grep foo /dev/zero

これが実際に動作するのを確認します。システム全体を引き継ぐ前に、ctrl-Cで停止する準備をしてください。

あなたがしていることをやりたいのなら、スキャンしたい/のサブディレクトリを列挙し、おそらくテキストファイルだけをチェックしたことを確認します。

cd /
find boot etc home lib lost+found media mnt opt root sbin tmp usr var -type f -exec grep needle {} /dev/null \;

リストの内容に注意してくださいnot/dev/proc/sys、または/selinuxが含まれています。

2
MadHatter

そのためにfind + xargs + grepを使用してみてください。

find /there -type f :MaybeSomeRestrictingFlagsLikeSizeNotBigger500MB_or_FS_type_if_u_know_its_exactly_on_EXT3_AndSoOn: -print0 | xargs -0r grep needle /dev/null

(/ dev/nullは、ファイルが1つしか見つからなかった場合でも、grepでファイル名を出力します)

2
poige

なぜ終了しないのかわかりませんが、通常は「fgrep-R」で動作します。

1
Thorsten

そのコマンドからdevとprocを除外したい場合があります。代わりにfindを使用して実行し、特別なファイルを除外します。

find . -type f -exec grep -H "My search string" '{}' \; -print 
0
pehrs

他のいくつかが指摘しているように、奇妙な結果を生成するいくつかの「ファイル」でgrepを使用しているため、エラーが発生しています。たとえば、grep XXX/dev/zeroは永久に続きます。

まず、/ dev /や/ proc /などのディレクトリを検索から除外します。もう1つの方法は、「ファイル」のみを検索し、他のタイプは検索しないことです。

また、grepの引数リストが長すぎると、次のエラーが発生します。

bash: /bin/grep: Argument list too long

次のようなループでこれを回避できます。

for i in `find -type f /`; do grep -H "sample string" $i; done

または、findから実行することで、ボートに浮かぶものは何でも。

find / -type f -exec grep -H "sample string" '{}' \; -print 

これにより、各ファイルが検索されてgrepさ​​れます。ファイルを見つけるたびにgrepを生成するのは非効率的であると指摘する人もいますが、文字通りすべてのファイルでその文字列を検索する必要があるため、「非効率的」な処理を行う必要があります。

0
Dave Drager