ワイルドカードが埋め込まれた「検索」検索で隠しファイルとディレクトリを除外/無視する方法は?


119

開始(「テキスト」の前後ワイルドカードに注意してください)

find . -type f -name '*some text*'

すべての隠しファイルとディレクトリをどのように除外/無視できますか?

私はすでにグーグルで長すぎて、いくつかのプルーンに出くわしました!(感嘆符)パラメータ、ただしちょうど機能する適切な(そしてpar約的な)例はありません

配管 |には、grepオプションになりますし、私もその一例を歓迎したいです。しかし、主に私は簡単なワンライナー(またはスタンドアロンのワンライナーのカップル、同じコマンドラインの目標を達成するためのさまざまな方法を示す)に興味があるだけ使ってfind

ps:Linuxでファイルを検索し、特定のディレクトリを除外することは密接に関連しているように見えますが、a)はまだ受け入れられておらず、b)関連しているが区別が異なりますが、c)インスピレーションを提供し、混乱を特定するのに役立ちます!

編集

find . \( ! -regex '.*/\..*' \) -type f -name "whatever"、動作します。正規表現は、「何でも、次にスラッシュ、次にドット、そして何でも」(つまり、すべての隠しファイルとサブフォルダーを含むフォルダー)、および「!」を探します。正規表現を無効にします。


編集で尋ねた内容には役立ちませんが、ここで私の質問とその答えを見てください:unix.stackexchange.com/q/69164/15760および答えのリンク。

回答:


134

これは、隠しファイルとディレクトリをスキップして、ディレクトリの子孫であるすべてのファイルを印刷します。

find . -not -path '*/\.*'

そのため、some textその名前にファイルを探していて、隠しファイルとディレクトリをスキップしたい場合は、次を実行します:

find . -not -path '*/\.*' -type f -name '*some text*'

説明:

-pathオプションがチェックにパス全体の文字列に対してパターンを実行します。*はワイルドカード、/ディレクトリ区切り記号、\.ドット(特別な意味を避けるためにエスケープする必要があります)、および*別のワイルドカードです。-notこのテストに一致するファイルを選択しないことを意味します。

find前のコマンドで隠しディレクトリを再帰的に検索するのを避けるほどスマートだとは思わないので、速度が必要な場合は次の-pruneように使用してください:

 find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*some text*' -print

最後に必要なことに注意してください-print!また、もしわからない-name '\.*' would be more efficient instead of -path`(パスがサブパスを探しているが、これらが出て剪定されるため)
artfulrobot

.この文脈での特別な意味は何ですか?
frostschutz

@frostschutz後のドットfindは、現在のディレクトリを意味しfindます。現在のディレクトリの下にあるすべてのファイルとディレクトリを参照します。後の引数pathは正規表現です。通常、ドットは「任意の文字」を意味するため、リテラルドットを意味するため、バックスラッシュでエスケープする必要があります。引数が後に-name ではない正規表現が、それは次のようにワイルドカードを展開する?と、*シェルが行うよう。
フリム

2
@frostschutz実際、考えてみると、.特別な意味を持つのは間違っているかもしれません。
Flimm

1
@Flimmうん、エスケープする必要はありません.。私の知る限り承知しているとして、これらのみをエスケープする必要があります*?[]
thdoan

10

これは、BSD、Mac、Linuxでも正常に動作するドットファイルを除外する数少ない方法の1つです。

find "$PWD" -name ".*" -prune -o -print
  • $PWD 現在のディレクトリへのフルパスを出力して、パスが次で始まらないようにします ./
  • -name ".*" -prune ドットで始まり、降順しないすべてのファイルまたはディレクトリに一致します
  • -o -printは、前の式が何とも一致しなかった場合にファイル名を印刷することを意味します。-printまたは-print0を使用すると、他のすべての式はデフォルトで印刷されません。

「驚くほど複雑」について説明/詳しく説明してください。すでに与えられた答えとあなたの答えは反対の証拠を与えるように見えます...?
ナッツについてのナッツ

2
「驚くほど複雑」はおそらく過剰です。要点を得るために答えを言い換えました。私が投稿した回答は理解するのが難しく、マニュアルページを非常に注意深く読まないと見にくいと思います。GNU find のみを使用している場合、さらに可能な解決策があります。
エラドマン

-o ... -print役に立ちます。使用するにはfind ... '!' -name . -name '.*' -prune -o ... -print、$ PWDを含めるよりも便利ながあります。
ロジャーパテ

4
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)

すべての隠しディレクトリ、および$ DIRの下の隠しファイルを除外します


これは完璧な答えです。すべてのファイルを再帰的に検索しますが、ディレクトリと隠しファイルの行項目は除外します。ありがとう!
カイルファリス

2

答えは、私はもともと上記の私の元の質問に、「編集」として投稿しました:

find . \( ! -regex '.*/\..*' \) -type f -name "whatever"、動作します。正規表現は、「何でも、次にスラッシュ、次にドット、そして何でも」(つまり、すべての隠しファイルとサブフォルダーを含むフォルダー)、および「!」を探します。正規表現を無効にします。


同様ですが、現在のフォルダーのみ:find . \( ! -regex './\..*' \) -type f -maxdepth 1 -print
phyatt

2

findそのために使用する必要はありません。シェル自体でglobstarを使用するだけです:

echo **/*foo*

または:

ls **/*foo*

where **/は、再帰的にフォルダを表し、名前に含まれる*foo*ファイルを表しますfoo

デフォルトでは、using lsは非表示のファイルとディレクトリを除くファイル名を印刷します。

グロビングを有効にしていない場合は、で実行しshopt -s globstarます。

注:新しいグロブオプションは、Bash 4、zsh、および同様のシェルで機能します。


例:

$ mkdir -vp a/b/c/d
mkdir: created directory 'a'
mkdir: created directory 'a/b'
mkdir: created directory 'a/b/c'
mkdir: created directory 'a/b/c/d'
$ touch a/b/c/d/foo a/b/c/d/bar  a/b/c/d/.foo_hidden a/b/c/d/foo_not_hidden
$ echo **/*foo*
a/b/c/d/foo  a/b/c/d/foo_not_hidden

5
lsその必要はありません!echo **/*foo*
ケビンコックス

@kenorb(および@ kevin-cox)。もう少し詳しく教えてもらえますか?なぜglobstar(= *)はここでどのように機能するのですか?スラッシュ/は何をしますか?
ナッツについて

@nuttyaboutnatty /はフォルダーを意味し、ディレクトリをファイル名から分離します。*基本的にすべてを表します。
ケノーブ

@kenorb yes-but:そのワンライナーは元の質問にどのように役立ちますか?
ナッツについて

1
@nuttyaboutnatty例を明確にし、追加しました。隠されたファイルを無視してファイルを見つけるのに役立ちます。
ケノーブ

1

@Flimmの答えは、特にfindが隠しディレクトリに降りることを防ぐため、良いです。私はこの単純化を好む:

一般に、すべての隠しパス(通常のファイル、ディレクトリなど)を除外するには:

find <start-point> -path '*/.*' -prune -o <expression> -print

たとえば、作業ディレクトリを開始点-name '*some text*'として、および式として使用します。

find . -path '*/.*' -prune -o -name '*some text*' -print

@Flimmの答えが示唆するものとは対照的に、隠しファイルや隠しディレクトリはありません。この-path '*/.*'式は.、ファイル区切り文字の直後にあるすべてのパス(通常のファイル、ディレクトリなど)に当てはまります/。したがって、この行は隠しファイルとディレクトリの両方を削除します。

隠しディレクトリを除外しながら隠しファイルを許可すると、さらにフィルターが必要になります。これは、-type dプルーニングされる式に含める場所です。

find <start-point> -type d -path '*/.*' -prune -o <expression> -print 

例えば:

find . -type d -path '*/.*' -prune -o -name '*some text*' -print

この場合、-type d -path '*/.*'あるtrueディレクトリのみのために、そしてそのディレクトリのみが剪定されています。


0

findのようなきちんとした論理スイッチが-andあり、-not次のような2つのルールで一致するファイルを見つけるためにそれらを有利に使用できます。

$ touch non_hidden_file.txt .hidden_file.txt somethings/.another_hidden_file.txt                                                 

$ find . -type f -name '*hidden_file*' -and \( -not -name ".*" \)                            
./non_hidden_file.txt

ご覧のとおり、find2つのルール-name '*hidden_file*'を使用して 、-and \( -not -name ".*" \)両方の条件に一致するファイル名を検索します。ファイル名はそのhidden_file中にあり、先頭にドットはありません。括弧の前のスラッシュに注意してください- findサブシェルを定義するのではなく、引数として括弧を定義するために使用されます(それ以外の場合、括弧はスラッシュなしで意味します)


0
$ pwd
/home/victoria

$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort
/home/victoria/new
/home/victoria/new1
/home/victoria/new2
/home/victoria/new3
/home/victoria/new3.md
/home/victoria/new.md
/home/victoria/package.json
/home/victoria/Untitled Document 1
/home/victoria/Untitled Document 2

$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2

ノート:

  • . :現在のフォルダー
  • -maxdepth 1再帰的に検索するには削除
  • -type f:ディレクトリではなくファイルを検索(d
  • -not -path '*/\.*' :戻らない .hidden_files
  • sed 's/^\.\///g'./結果リストから先頭に追加されたものを削除します
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.