条件に合うファイルに対してコマンドを実行する方法

例えば、「現在のディレクトリ内にある PNG フォーマットの画像ファイルのファイルサイズを optipng コマンドで最適化したい」という要望があったとします。

PNG ファイルのファイルサイズの最適化については「OptiPNG で PNG ファイルの最適化を行う方法」をみてください。

ディレクトリ内には、PNG ファイルの他、JPEG ファイルなど混在しているので、ファイルの拡張子でフィルターをかけてファイルを探して、見つかったファイル名を optipng に渡すことになります。

こうした場合は、find コマンドを使うと便利です。

次のコマンドでは、拡張子でファイルを探し、見つかったファイル名を optipng コマンドに渡しています。

$ find . -type f -iname '*.png' -exec optipng -o5 {} \;

パラメータの説明をします。

最初のドット . は現在のディレクトリを表しています。ファイル検索の開始点になります。

-type f オプションで、ファイルのタイプとして f を指定することで、ディレクトリなどではなく「通常のファイル」を指定しています。

-iname '*.png' オプションで、ファイル名による検索を行っています。 -iname オプションは大文字小文字によらないファイル名の検索です。一方、-name とすると大文字小文字を区別します。

-exec optipng -o5 {} \; によって、見つかったファイルに対して実行するコマンドを指定しています。

-o5optipng コマンドのオプションです。最適化のレベルを指定しています。

{} の箇所は検索で見つかったファイル名で置き換えられます。

\;+ の違い

\; はコマンドの終わりを示しています。その他、+ で終わることもできます。

この違いは何でしょうか。

+ ではこの場合は {} のところが単一のファイル名ではなく、ファイルのリストを受けとります。

例えば、今、ファイルが三つ (file1, file2, File3) があり、それぞれに対して echo コマンドを実行してみましょう。

$ ls
file1  file2  File3  subdir
$ find . -type f -iname 'file*' -exec echo '---' {} \;
--- ./file1
--- ./File3
--- ./file2
$ find . -type f -iname 'file*' -exec echo '---' {} +
--- ./file1 ./File3 ./file2

\; で終わった場合はファイル名三つに対して、echo コマンドがそれぞれ 1 回ずつ実行されています。

しかし、+ の場合は、echo コマンドは一度だけ実行されています。

cat コマンドでファイルの内容を連結する時のように、 複数のファイル名を渡したい場合は + を使うと良いです。

上述の optipng の場合は、複数のファイル名を受け取れるので + をつけても構いません。 しかし、optipng の処理自体ファイルひとつひとつ行われるものなので、\; でも + でもどちらでも構いません。

ここでは find コマンドを使いましたが、find コマンドを使うと、ファイルの検索を様々な方法で行うことができます。 検索の方法について他の記事をみてください。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Linux 入門