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
NIXシステムの「ファイルタイプ」 は、通常のファイル、ディレクトリ、名前付きパイプ、文字特殊ファイル、シンボリックリンクなどです。これらは、find
がフィルタリングできるファイルのタイプです-type
オプション付き。
find
ユーティリティ自体では、「シェルスクリプト」、「JPEG画像ファイル」、またはその他のタイプの通常のファイルを区別できません。ただし、これらのタイプのデータはfile
ユーティリティによって区別される場合があります。このユーティリティは、ファイル内の特定の署名を調べてタイプを判別します。
さまざまなタイプのデータファイルにラベルを付ける一般的な方法は、それらの MIMEタイプ によるものであり、file
はファイルのMIMEタイプを判別できます。
file
を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
が含まれている場合、ゼロの終了ステータスで終了します。出力にその文字列が含まれていない場合、出力は0以外の終了ステータスで終了し、find
は次のファイルをすぐに続行します。ファイルがシェルスクリプトであることが判明した場合、find
コマンドはファイルのパス名(最後の-print
を出力しますが、他のアクションで置き換えることもできます)に進みます。
file -bi
コマンドは、ファイルのMIMEタイプを出力します。 Linux(および他のほとんどのシステム)のシェルスクリプトの場合、これは次のようになります。
text/x-shellscript; charset=us-ascii
少し古いバージョンのfile
ユーティリティがインストールされているシステムでは、
application/x-shellscript
一般的なビットは/x-shellscript
サブストリングです。
理由のため、macOSではfile -bI
の代わりにfile -bi
を使用する必要があることに注意してください(-i
オプションはまったく異なることをします) 。 macOSの出力はLinuxシステムの出力に似ています。
見つかった各シェルスクリプトでカスタムアクションを実行したい場合は、上記のfind
コマンドの-exec
の代わりに別の-print
を使用して実行できますが、できる
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 {} +
関連:
見つかったすべてのファイルに対してfind
を実行してから、興味のある結果を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"
誤検出の数を低く抑えるために、検索パターンをできるだけ期待に近づけることをお勧めします。
ファイル名に改行が含まれているファイルは、このアプローチで問題を引き起こす可能性があることに注意してください。
Perl
のFile::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' -- .