私の状況:
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/pizza
dir42/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
追加資料:
- 読み取り - 標準入力から1行を読み取ります。(POSIX)