
以下を使用してファイルを見つけることができることを知っています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
Unixシステムの「ファイル形式」一般ファイル、ディレクトリ、名前付きパイプ、文字特殊ファイル、シンボリックリンクなど、これらのfind
オプションを使用してフィルタリングできるファイル形式は次のとおりです-type
。
ユーティリティfind
自体は、「シェルスクリプト」、「JPEGイメージファイル」、または他のファイルを区別することはできません。一般的なファイル形式。ただし、このタイプのデータは、file
ファイルの内容の種類を決定するために、ファイル自体内の特定の署名を調べるユーティリティによって区別できます。
さまざまな種類のデータファイルにラベルを付ける一般的な方法は、MIMEタイプ、file
ファイルのMIMEタイプを決定できます。
一般ファイルのMIMEタイプを検出し、それを使用してシェルスクリプトのみを見つけるには、file
withを使用します。find
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
見つかったファイルで実行され、コマンド出力に文字列が含まれている場合は終了ステータス0で終了します/x-shellscript
。出力にこの文字列が含まれていない場合は、ゼロ以外の終了状態で終了し、find
次のファイルにすぐに続行されます。ファイルがシェルスクリプトであると確認されると、find
コマンドはファイルのパス名を出力し続けます(-print
最後のパスは他の操作に置き換えることもできます)。
このfile -bi
コマンドはファイルのMIMEタイプを出力します。 Linux(および他のほとんどのシステム)のシェルスクリプトの場合、これは次のとおりです。
text/x-shellscript; charset=us-ascii
このユーティリティの少し古いバージョンがインストールされているシステムでは、file
次の問題が発生する可能性があります。
application/x-shellscript
共通ビットは/x-shellscript
部分文字列です。
file -bI
macOSでは代わりに使用する必要がありますfile -bi
。理由(この-i
オプションはまったく異なる機能を果たします)。 macOSの出力はLinuxシステムの出力と似ています。
見つかった各シェルスクリプトに対していくつかのカスタムアクションを実行しますか?上記のコマンド-exec
の代わりに他のスクリプトを使用することもできますが、次のこともできます。-print
find
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 {} +
関連:
答え2
見つかった各ファイルを実行し、file
grepを介して興味のある結果を得ることができます。
# When looking for ASCII Text
find . -type f -exec file {} \; | grep "ASCII"
# or for MS Word Documents
find . -type f -exec file {} \; | grep "Microsoft Word"
間違った肯定一致の数を低く保つには、検索パターンを予想にできるだけ近づけることをお勧めします。
名前に改行を含むファイルはこの方法で問題を引き起こす可能性があります。
答え3
シェルの魔法をあまり含まない短い形式:
find . -exec sh -c "file '{}' | grep -q 'pattern'" \; -print
答え4
使用された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' -- .
File::LibMagic
同じアルゴリズムとヒューリスティックを使用してファイルタイプを推測しfile
ますが、ここではすべてが単一の呼び出しで実行されるため、perl
各ファイルに対して単一の呼び出しを実行するよりもはるかに効率的ですfile
。