Shell の find コマンド: オプション、正規表現など

UB3/informatics/commands_mac/find_mac

このページの最終更新日: 2024/02/03

  1. 概要: find とは
    • オプション
  2. 使用例 1: find, grep, ruby でファイルの中身を一括置換する
  3. 使用例 2: 特定の階層にあるファイルを一括削除 (一括移動)
  4. 使用例 3: 条件に合うファイルの個数を表示

広告

概要: find とは

find は、指定した規則に従ってファイルやディレクトリを検索するコマンドである (1)。

find 検索するディレクトリ 検索条件のオプション アクションのオプション

のように使う (1)。

  • ディレクトリ指定: 指定しない場合、カレントディレクトリが検索対象になる。find / や find . (カレントディレクトリ以下) を基本形として覚えておくと、ファイル名とディレクトリのどっちが先だったか迷わずにすむ。
  • 検索条件: -name などのオプションを使って指定する。順番はアクションのオプションと交換可能。指定しない場合、全てのファイルおよびディレクトリが検索結果としてヒットする ようになる。
  • アクション: -exec などのオプションを使って指定する。指定しない場合、-ls が選ばれる。つまり、検索結果が単にターミナル上に吐き出される。

オプション

option の部分には、以下のようなオプションを並べて書いていくことができる。

-name "filename"

指定した文字列を名前にもつファイルおよびディレクトリを検索する。

ゆえに、単にコンピューター内を全検索したいときは find / -name *.jpg などでよい。

-depth

階層を指定する。

-type

-type f でファイルを検索、-type d でディレクトリを検索。

-usr "username"

指定したユーザーが所有するファイルおよびディレクトリを検索する。

-ls 詳細を一覧表示する
-print 検索結果の標準出力
-fprint "filename" 検索結果を指定したファイルに書き出す。
-exec "command" {} \;

検索結果をコマンドに引き渡して実行する。

「使用例」に、このオプションを使って特定の階層にあるファイルを一括削除する方法を示してある。

-and, -or, -not

複数の条件や、~以外という条件を設定して検索できる。


使用例1: find, grep, ruby でファイルの中身を一括置換する

ub2 というフォルダに html ファイル を格納し、このサイトの一部を作っていた際、始めはサイドバーの縦幅を 1500 px に指定してあったが、内容が増えてきたので全ての html ファイルで 2000 px に置換することにした (2)。システムは Mac OS X Mavericks, Ruby のバージョンは 2.0.0-p481。

この作業は 3 つの段階から成る。

  1. find で目的のファイルを探す。
  2. その中で、grep で目的の文字列を探す。
  3. ruby で一括置換する。

まずは、それぞれのページの html ファイルを ub2 というフォルダ内で検索する。ワイルドカードと " " を使って、

$ find ub2 -name "*.html"

これで、ub2 フォルダ内にある html ファイルの一覧が表示される。次に、この結果を grep に渡してサイドバーを指定している部分を検索させる。このサイトのサイドバーは iframe を使って表示させており、タグは

<iframe width="175px" scrolling="no" height="1500px" frameborder="0" src="../../sidebar.html"></iframe>

である。

find -name "*.html" | xargs grep -l 1500px

とすると、1500px という文字列を含むファイルの一覧が表示される。grep の -l は、結果をファイル名のみで表示するオプションである。ここで、<iframe width="175px" としてしまうと < が 命令とみなされてエラーになるので注意。また xargs は結果を次のコマンドに引き渡すということ。


次に、上記の検索結果を Ruby に渡して一括置換するコマンドを追加する。

$ find -name "*.html" | xargs grep -l 1500px | ruby -i -ep 'gsub!(/1500px/,"3000px")'

文献 2 に従うとこれで一括置換できるはずなのだが、なぜかうまく動かなかった。-ep を -e -p に変える、gsub を $_.gsub に変えるなどしてみたが駄目だった。


そこで grep を使わない方法 (3) を検討、結果的にこれでうまく置換することができた。コマンドの意味はよくわからない。

$ find 探したい場所 -type f -name '対象ファイル名' -print0 | xargs -0 ruby -i -p -e '$_.gsub!(/置換前の文字列/, "置換後の文字列")' が構文と書いてあったので、


find ub2 -type f -name "*.html" -print0 | xargs -0 ruby -i -p -e '$_.gsub!(/1500px/,"3000px")'


とした。今回は他の部分に 1500px という文字列はなかったのでこれで良かったが、" " を含む長い部分での置換もできるようにしておきたい。ちなみに、以下のソフトでもテキストの一括置換は可能である。コマンドラインに慣れていない場合は、これらを使うのも良い。

  • TextSS: Windows で使えるテキストエディタ。一括置換可能。
  • TextWrangler: Mac で使えるテキストエディタ。一括置換可能。

使用例 2: 特定の階層にあるファイルを一括削除 (一括移動なども可能)

find には、結果を他のコマンドに引き渡す -exec オプション がある。xargs との違いはよくわからない。-exec オプションを利用し、検索結果を rm に引き渡せば、ヒットするファイルを一括で削除できることになる。

このサイトでは、コメント欄を設置する 際に zpcomment_ファイル名.php というファイルを作って、html ファイルを同じフォルダに置いている。サーバーにアップロードしたのち、このファイルがローカルにあると邪魔になるので、文献 4 の方法で以下のように一括削除した。見にくいけれど、zpcomment のあとにはアスタリスクがついている。

find . -name "zpcomment*" -exec rm {} \;

find の次のドットは、現在自分がいる階層以下という意味である。次回はここをフォルダ指定にしておいた方が、予期しない結果を減らせて安全だろう。rm の次の {} \; の意味はよくわからない。

使用例 3: 条件に合うファイルの個数を表示

ファイルの個数のみが知りたい場合、適切なオプションは無いようで、結果を行数カウントのコマンド wc に引き渡すのが普通のようである。つまりこのような感じ。

find 対象ディレクトリ -name "*.html" | wc -l

これで、.html という拡張子のファイルの個数を再帰的に調べることができる。-l は行数のみを表示させる wc のオプション。これがないと結果は wc の標準出力、つまり「行数 単語数 文字数」の 3 つの数字になるが、ファイルの個数を知りたい場合には、単語数と文字数にはあまり意味はないだろう。


広告

References

  1. find どこにあるかわからないファイルを検索. Link.
  2. rakkyoo の備忘録 複数のファイル内の文字列を一括置換. Link.
  3. 文字列一括置換 Link.
  4. フォルダ下にある特定のファイルを速攻で消す方法 (Mac & Linux) Link: Last access 06/01/2017.
  5. 今さらながらfindパイセンについてまとめてみた. Link: Last access 2024/01/27.

コメント欄

サーバー移転のため、コメント欄は一時閉鎖中です。サイドバーから「管理人への質問」へどうぞ。