多くのディレクトリでgrepを使用しますが、すべてのサブディレクトリではなく、各ディレクトリの特定のサブディレクトリのみを検索します。

多くのディレクトリでgrepを使用しますが、すべてのサブディレクトリではなく、各ディレクトリの特定のサブディレクトリのみを検索します。

私の状況:

dir1 
  subdir1
      FooFile
  subdir2

dir2 
  subdir1
      FooFile
  subdir2

したがってcd dir1、私は簡単に次のことを行いfind . | xargs grep "Foo"ますFoo

問題は、サブディレクトリとファイルが多すぎるため、検索に時間がかかることです。各ホームディレクトリに再帰的に移動し、具体的にはサブディレクトリ(subdir1)に移動し、次にgrepに移動したいと思います。

Fooすべてのディレクトリに含まれるすべてのファイルの名前を一覧表示する最良の方法は何ですか?名前が異なる各ディレクトリの場合、subdir1常に1つのレベルより下にあり、dir1常にsubdir1正確に名前が付けられます。

答え1

何について

grep "foo" */subdir1/*  */subdir1/.*

? (現在の問題によると、これは声明に合うようです。シェルが完全なリストをgrepに供給できないほど「subdir1」サブディレクトリが多すぎない限り。

ファイルに「foo」が表示されることを確認するには、-qを追加して0で終了するかどうかをテストします。

また、再帰 grep を実行し、不要なものを削除することもできます (多くの I/O ですが簡単です)。

grep -r "foo" . | grep "^\./[^/][^/]*/subdir1/[^/][^/]*:"

(以下の注を参照してください:ここでは、名前に「:」が含まれていて、ファイルにfooが含まれていても、subdir1でファイル名を見つけたように動作します。最初のgrepでは最初の「./firstleveldir/」という名前が表示されないため、2番目のgrepはそれを無視します...)

答え2

見たいなら存在するそして下すべての(サブ)ディレクトリはsubdir1 上から1レベル下に名前が付けられます。

find */subdir1 …

以下の書類をお探しの場合名前含まれていますFoo。できます。

find */subdir1 -type f -name "*Foo*" -print

それともこれを行うことができます。

find */subdir1 -type f -print | grep "Foo"

しかし、これにはすべてのファイルが含まれます。ディレクトリに 名前には、Fooなどの文字列が含まれています。dir42/subdir1/Foods_I_Like/pizzadir42/subdir1/Foods_I_Like/chicken

探しているならファイルに次のものが含まれています Foo (つまり、誰のコンテンツを含むFoo)、あなたはできます

find */subdir1 -type f -print | xargs grep "Foo"

メモ:

  • これはfind次の要約(使用)のために機能します。
    探す[オプション][初期点...][表現する]
    つまり、次findのように複数のソースから一度呼び出すことができます。
    探す   ディレクトリ1/サブディレクトリ1ディレクトリ2/サブディレクトリ1 [表現する]
  • これは、名前にスペースが含まれているファイルとディレクトリでうまく機能します。
  • ファイルをお探しの場合またはディレクトリその名前はそのコマンドに含まれるか省略されますFoo-type f
  • もちろん引用する必要があり"*Foo*"、引用することはできません*/subdir1。引用は"Foo"オプションです。問題にはなりませんが、特殊文字を含まない単語は引用する必要はありません。
  • -printこれは基本操作なので省略できます。

答え3

次のスクリプトを使用してこれを実行できます。

#!/bin/sh
find . -type d | while IFS= read -r pathname
do
    for name in "$pathname"/subdir1/*Foo*
    do
        [ -f "$name" ] && echo "$name"
    done
done

パス名の改行に関する一般的な警告です。次のツリーでテストしてみてください。

./dir2
./dir2/subdir1
./dir2/subdir1/FooFile
./dir2/subdir2
./subdir1
./subdir1/FooFile
./dir spacew
./dir spacew/subdir1
./dir spacew/subdir1/FooFile
./dir spacew/subdir2
./dir1
./dir1/subdir1
./dir1/subdir1/FooFile

製作された台本

./subdir1/FooFile
./dir2/subdir1/FooFile
./dir spacew/subdir1/FooFile
./dir1/subdir1/FooFile

の使用に関して質問はあいまいです(作成されたとおり、シェルワイルドカードの代わりに正規表現を使用できることを除いてとgrep違いはありません)。echoまたは、以下をgrep直接使用することもできます。

#!/bin/sh
find . -type f -name '*Foo*' | grep -E 'subdir1/Foo[^/]*$' | while IFS= read -r pathname
do
    echo "$pathname"
done

追加資料:

関連情報