複数のパターンに一致する `find -name`パターン


335

コマンドを使用して、ディレクトリ内のすべてのpythonおよびhtmlファイルのリストを取得しようとしましたfind Documents -name "*.{py,html}"

次に、manページが表示されました。

パターン内の波括弧( '{}')は特別であるとは見なされません(つまり、find。-name 'foo {1,2}'は、ファイルfoo1およびfoo2ではなく、foo {1,2}という名前のファイルと一致します。

これはパイプチェーンの一部であるため、実行時に一致する拡張子を指定できるようにしたいと思います(ハードコーディングなし)。findがそれを実行できない場合は、perlのワンライナー(または同様の)で問題ありません。

編集:私が最終的に思いついた答えには、あらゆる種類のがらくたが含まれており、少し長くもあるので、スクラッチしようとした元のかゆみに対する答えとして投稿しまし。より良い解決策があれば、遠慮なくハックしてください。



頻繁に見過ごされ使用されていないユーティリティもですがlocate、内部のupdatedbが最新ではない可能性があるという警告があります。しかし、それは速いです。
マイケル2018年

この質問は、Unix&Linuxに属しているため、オフトピックとして閉じることに投票します
Dan Dascalescu

回答:


481

-o「または」を意味するを使用します。

find Documents \( -name "*.py" -o -name "*.html" \)

コマンドラインをプログラムでビルドする必要がありますが、これはそれほど簡単ではありません。

bash(またはWindowsのCygwin)を使用していますか?もしそうなら、これを行うことができるはずです:

ls **/*.py **/*.html

プログラムで構築する方が簡単かもしれません。


3
私はzshを使用しています。これは、原則として、すべてのバシズムに加えて、それ以上をサポートしています。
Xiong Chiamiov、2009

12
Zshは**再帰検索をサポートしています。Bashがサポートするのは、バージョン4.0以降、およびでのみshopt -s globstarです。
ephemient 2009

2
-o argsはいくつ持つことができますか?作成する.gcda(カバレッジデータ)ファイルの潜在的に大きなリストを持っています
Jasper Blues

40
-nameを使用して-execいる場合は、2つのをブラケットで囲む必要があります。例find Documents \( -name "*.py" -o -name "*.html" \) -exec file {} \;
artbristol 2014年

2
@artbristolコメントは、たとえば、-print0スペースを含むファイル名を処理するためにを追加する場合に非常に重要です。
nimrodm

63

findの一部のエディションは、主にLinuxシステム上にあり、おそらく他のエディションも-regexおよび-regextypeオプションをサポートしており、regexと一致する名前のファイルを検索します。

例えば

find . -regextype posix-egrep -regex ".*\.(py|html)$" 

上記の例でトリックを実行する必要があります。ただし、これは標準のPOSIX検索機能ではなく、実装に依存します。



12
よりシンプル:find . -regex ".*\.\(py\|html\)$"これは、デフォルトではEmacsスタイルの正規表現を検索するために機能します。これはわずかに異なり、regextypeを指定する必要はありません。
robru 2013

2
多くの式-regextype posix-egrepがある場合は便利です(そうしないと、多くの文字をエスケープする必要があります)。これは私がWindowsディストリビューションのzipを構築するのdist-フックのために使用しましたfindコマンドである(変化にファイルを検索し、ファイルにDOS-EOLにそれらを変更します): find -regextype posix-egrep -regex ".*(\.([chyl]|def|cpy|cob|conf|cfg)|(README|ChangeLog|AUTHORS|ABOUT-NLS|NEWS|THANKS|TODO|COPYING.*))$" -exec sed -i -e 's/\r*$/\r/' {} \;
サイモンSobisch

32

次のよう-nameに区切って、プログラムでさらに句を追加できます-or

find Documents \( -name "*.py" -or -name "*.html" \)

または、代わりに単純なループを実行します。

for F in Documents/*.{py,html}; do ...something with each '$F'... ; done

@ user2284570:*.pyファイルがないか、の奇妙なバージョンがありfindます。上記のコマンドは問題なく機能します。
Stephan202 2014

いいえ、使用してい-inameます。*.py最後の位置iname *.html最初の式も同様)に書き込む場合にのみファイルを返します。Debianでコマンドを使用します。
user2284570 2014

引用符を使用していますか?それは非常に重要です。
Stephan202 2014

1
-orまたは-oですか?
Stephane

1
@StephaneEybert:どちらでもかまいませんが、後者のみがPOSIXに準拠しています(manページによると)。
Stephan202 2014

16

これにより、Linux上のすべての.cまたは.cppファイルが検索されます

$ find . -name "*.c" -o -name "*.cpp"

追加の変更を行わない限り、エスケープされた括弧は必要ありません。ここで、manページから、パターンが一致する場合はそれを印刷します。おそらく、彼らは印刷を制御しようとしています。この場合、-printは条件として機能し、「ANDされた」条件になります。.cファイルが印刷されなくなります。

$ find .  -name "*.c" -o -name "*.cpp"  -print

ただし、元の回答が気に入った場合は、印刷を制御できます。これにより、すべての.cファイルも検索されます。

$ find . \( -name "*.c" -o -name "*.cpp" \) -print

すべてのc / c ++ソースファイルの最後の例

$ find . \( -name "*.c" -o -name "*.cpp"  -o -name "*.h" -o -name "*.hpp" \) -print

11

同様のニーズがありました。これは私のために働きました:

find ../../ \( -iname 'tmp' -o -iname 'vendor' \) -prune -o \( -iname '*.*rb' -o -iname '*.rjs' \) -print

3
完璧です。しかし、それがなければ動作しないのは少し奇妙だと思います()
pedrofurla 14

* .c * .cppまたは* .ccに一致するファイルを見つけたいと思いました。2つの-nameパターンだけで括弧は必要ありませんでしたが、3つの-nameパターンと2つの-oパターンfind -name "*.cpp" -o -name "*.c" -o -name "*.cc" -print0を結合すると、ペアの括弧を使用して2番目のor演算子をグループ化します。find -name "*.cpp" -o \( -name "*.c" -o -name "*.cc" \) -print0常に「true」である-print0がロジックに影響した可能性があります。
カーディフの宇宙人、

5

私のデフォルトは:

find -type f | egrep -i "*.java|*.css|*.cs|*.sql"

findブレンダン・ロングとステファン202らによる少ないプロセスの集中的な実行のように:

find Documents \( -name "*.py" -or -name "*.html" \)


3
これはegrep正規表現の正しい使い方ではなく、正規表現を使用する必要のあるシェルグロブです。(また、一般的なfind使用方法は次のとおりですfind {directory} [options...] [action]、独自の実装に応じて、directoryにデフォルト設定があり.、およびactionデフォルトに-print、私は明示的になります。)ので、代わりに、使用のようなもの:find . -type f -print | egrep -i '\.java$|\.css$|\.cs$|\.sql$' 本当に速いの代替として、しかし、またし、find1はまたかもしれません、locate同様の方法で試してください(ファイルリストの内部データベースを照会するため、必ずしも最新ではありません)
マイケル

2
#! /bin/bash
filetypes="*.py *.xml"
for type in $filetypes
do
find Documents -name "$type"
done

シンプルですが動作します:)


1

いくつかのファイルを除いて、子ディレクトリ内のすべてのファイルを削除する必要がありました。次は私のために働きました(指定された3つのパターン):

find . -depth -type f -not -name *.itp -and -not -name *ane.gro -and -not -name *.top -exec rm '{}' +

1

パターン内の波カッコは、\(\)名前のパターンを持つために必要ですor

find Documents -type f \( -name "*.py" -or -name "*.html" \)

and演算子付きの名前パターンの場合は必要ありませんが

find Documents -type f ! -name "*.py" -and ! -name "*.html" 

0

これは、AIX Kornシェルで機能します。

find *.cbl *.dms -prune -type f -mtime -1

これは、探している*.cbl*.dmsのサブディレクトリをスキップし、現在のディレクトリのみで、1日齢です。


0
find MyDir -iname "*.[j][p][g]"
+
find MyDir -iname "*.[b][m][p]"
=
find MyDir -iname "*.[jb][pm][gp]"

2
後者はfoo.jmgに一致しますが、上位2つは一致しません。
Copper.hat 2017

0

どうですか

ls {*.py,*.html}

ファイル名に.pyまたは.htmlで終わるすべてのファイルがリストされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.