やりたいこと
- 削除したいファイルをfindで見つけて、それをrmコマンドに渡したい
- git blame したいけどファイルのフルパスがわからない
find で見つけたファイルを他のコマンドに渡せたら便利
方法
- 削除したい時
# これだとダメ
find . -name node-modules -type d -exec rm -rf {} \;
find: ‘./project/target/node-modules’: そのようなファイルやディレクトリはありません
# \; ではなく + を使うとうまくいく。理由はいろいろ説明してあったのでメモしておく find . -name node-modules -type d -exec rm -rf +;
- git blameしたい時
$ find . -name plugins.sbt -exec git blame {} +
「(バックスラッシュ);」 ではダメな理由
-exec 何かコマンド {} \;
で 前のfindがみつけたパスを {} に展開してコマンドを実行する。
;
はシェルの中でコマンド区切りとして認識されるが、 find に解釈させるために \(バックスラッシュ)
でエスケープする必要がある。
試しに \
無しで実行してみると、区切りがわかないためか以下のエラーが出る
find: `-exec' に引数がありません
\;
を使うと、find でパスが見つかるたびに -exec 後のコマンドを逐一実行しているとのこと。
そのため、rm -r
で ディレクトリ以下全て削除する場合には、すでに消したパスを消そうとしているため、そのファイルやディレクトリはありませんというエラーが出てしまっている。
一方の +
を使った方式では find で見つかったファイルのパスをまとめて、-exec のコマンドの引数として連ねて、実行できるらしい。そのためエラーが発生せず実行できる。
また、まとめて実行するので性能もいいとのこと。
参考:
SofwareDesign 2020/09号
https://gihyo.jp/magazine/SD/archive/2020/202009
Comments