web-dev-qa-db-ja.com

ファイル名パターンのリストと一致しないファイルを見つける

(2Tドライブ上の約900Kファイルのうち)無関係なファイルを見つけて識別する必要があることに気づきました。保持したいファイルがたくさんあり、これらの既知の適切なファイルのファイル名パターンがあります。私が欲しいのは、どのパターンにも適合しないファイルを見つけることです。

ファイル名パターンのリストに一致しないファイルを見つけるにはどうすればよいですか?

findを実行してすべてのファイルのリストを取得できます。grep -v結果に、ファイルに保存されているパターンのリストを使用します。これは標準的な方法ですか、それともこれらの非準拠ファイルを見つける簡単な方法はありますか?


説明-回答に基づいて、ここにもう少し情報があります。多数のパターン(> 20、おそらく> 100)があると予想します。それらをファイルに保存し、簡単に新しい方法を追加したい(壊れやすい)findパラメータの大きなリストを直接編集することは避けたいですが、そのリストを作成するとうまくいくかもしれません。

7
ChuckCottrill

Perlについて言及しているので...

#!/usr/bin/Perl

use strict;
use warnings;
use File::Find qw{find};

my %patterns;
while (<>) {
  chomp;
  $patterns{$_}++;
}

die "No pattern supplied\n" unless keys %patterns;

find( 
    sub{
           my $matches_a_pattern=0;
           for my $pattern (keys %patterns){
               my $glob_pattern = $pattern;
               for($glob_pattern){
                   s/\./\\./g;
                   s/\*/.*/g;
                   s/\?/./g;
               }
               $matches_a_pattern++ if ( /\Q$pattern\E/ or /$glob_pattern/);
           }

           print "$File::Find::name\n" unless $matches_a_pattern;
     }
    , '.' )

これを次のように呼び出します

/path/to/my/script file_with_patterns

.最後に歩きたい木のてっぺん。

3
Joseph R.

find(1)は、必要なことを実行するのに十分強力です。かっこを使用してすべての準拠名を式にまとめ、次に否定してnon-conformingファイル名を表示します。たとえば、すべてのファイルを表示するにはnotという名前の*.txt*.bz2、または*.Zip

$ find . \! \( -name \*.txt -o -name \*.bz2 -o -name \*.Zip \)

GNUおよびBSD findを指定すると、-notの代わりに\!を使用できます。POSIXに準拠していませんが、エスケープは必要ありませんシェルがそれを解釈しないようにするため。

ファイル内のパターンから式を構築するには、シェルスクリプトの小さな問題です。

#!/bin/sh
set --
while IFS= read -r pattern
do
    set -- "$@" -o "$pattern"
done < .fnpatterns
if [ $# -ne 0 ]; then
  shift
  set -- -not \( "$@" \)
fi
find . "$@"

これは、現在のディレクトリに.fnpatternsというファイルがあり、1行に1つのパターンがあることを前提としています。上記のワンライナーを模倣するには、以下を含める必要があります。

*.txt
*.bz2
*.Zip

シェルスクリプトはパターンの*文字をエスケープすることに注意してください。

これを任意に複雑にすることができます。いくつかのアイデア:

  • -type ffindコマンドに追加して、ディレクトリではなく通常のファイルのみを表示するようにします。

  • 固定された場所にあることを期待するのではなく、引数としてパターンファイル名を渡します

  • パターンファイルはそのままにしておきますが、ビルドされたfindコマンドに-o -name .fnpatternsを追加して、出力に表示されないようにします。 (これにより、ビルドされた式でshiftハックがリード-oを "食べる"必要もなくなります。)

  • -execなどを使用して、findコマンドにアクションを追加します。

  • パターンファイルで空白行またはコメントを許可する

19
Warren Young