ファイルの種類でファイルを見つける方法は?


9

次を使用してファイルを検索できることを知っていfindますfind . -type f -name 'sunrise'。結果の例:

./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise

また、ファイルのファイルタイプを判別できることも知っていますfile sunrise。結果の例:

sunrise: PEM RSA private key

しかし、どうすればファイルの種類でファイルを見つけることができますか?

たとえば、my-find . -type f -name 'sunrise' -filetype=bash-script次のとおりです。

./astronomy/sunrise
./schedule/sunrise

1
--filetypeファイルの種類を示すfindコマンドやその他のオプションはありません。実行できる唯一のことは、bashスクリプトを探している場合や、Perlスクリプトなどの行を探し--exec file {} \;ているgrep Bourne場合に、パイプを使用することですgrep Perl
Nasir Riley

回答:


13

Unixシステムの「ファイルタイプ」とは、通常のファイル、ディレクトリ、名前付きパイプ、キャラクタースペシャルファイル、シンボリックリンクなどのことです。これらは、オプションでfindフィルタリングできるファイルのタイプです-type

findユーティリティは、それ自体で「シェルスクリプト」、「JPEG画像ファイル」または任意の他の区別することはできません通常のファイルの種類。ただし、これらのタイプのデータはfileユーティリティによって区別される場合があります。ユーティリティは、ファイル自体の特定の署名を調べて、そのタイプを判別します。

さまざまなタイプのデータファイルにラベルを付ける一般的な方法は、そのMIMEタイプでありfile、ファイルのMIMEタイプを判別できます。


filewith findを使用して通常のファイルのMIMEタイプを検出し、それを使用してシェルスクリプトのみを検索します。

find . -type f -exec sh -c '
    case $( file -bi "$1" ) in
        */x-shellscript*) exit 0
    esac
    exit 1' sh {} ';' -print

または、を使用してbash

find . -type f \
    -exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';' \
    -print

その名前のスクリプトのみを検出する場合は-name sunrise、その前に追加し-execます。

上記のfindコマンドは、現在のディレクトリ内またはその下にあるすべての通常のファイルを検索し、そのようなファイルごとに短いインラインシェルスクリプトを呼び出します。このスクリプトはfile -bi、見つかったファイルに対して実行され、そのコマンドの出力に文字列が含まれている場合、ゼロの終了ステータスで終了します/x-shellscript。出力にその文字列が含まれていない場合、出力はゼロ以外の終了ステータスで終了findし、次のファイルですぐに続行します。ファイルがシェルスクリプトであることが判明した場合、findコマンドはファイルのパス名(-print最後の)の出力に進みます。これは、他のアクションで置き換えることもできます。

このfile -biコマンドは、ファイルのMIMEタイプを出力します。Linux(および他のほとんどのシステム)のシェルスクリプトの場合、これは次のようになります。

text/x-shellscript; charset=us-ascii

fileユーティリティのバージョンが少し古いシステムでは、

application/x-shellscript

一般的なビットは/x-shellscriptサブストリングです。

macOSでは、理由file -bIfile -biためにではなく、を使用する必要があることに注意してください(オプションはまったく異なるものを実行します)。macOSの出力はLinuxシステムの出力に似ています。-i


見つかった各シェルスクリプトでカスタムアクションを実行したい場合は、上記のコマンドの-exec代わりに別のアクションを実行できますが、次のようにすることもできます。-printfind

find . -type f -exec sh -c '
    for pathname do
        case $( file -bi "$pathname" ) in
            */x-shellscript*) ;;
            *) continue
        esac

        # some code here that acts on "$pathname"

    done' sh {} +

または、とbash

find . -type f -exec bash -c '
    for pathname do
        [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue

        # some code here that acts on "$pathname"

    done' bash {} +

関連:


1

あなたは、execができfind、すべてのFOUNDファイルにして、あなたが興味のある結果をgrep。

# When looking for ASCII Text
find . -type -exec file {} \; | grep "ASCII"
# or for MS Word Documents
find . -type f -exec file {} \; | grep "Microsoft Word"

誤検出の数を低く抑えるために、検索パターンをできるだけ期待に近づけることをお勧めします。

ファイル名に改行が含まれているファイルは、このアプローチで問題を引き起こす可能性があることに注意してください。


0

perlFile::LibMagicモジュールを使用:

perl -MFile::LibMagic=:easy -MFile::Find -le '
  find sub {
    print $File::Find::name if
      $_ eq "sunrise" and
      -f and
      MagicFile$_ eq "PEM RSA private key"
  }, @ARGV' -- .
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.