いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

find と xargs を組み合わせてコマンド実行

概要

とても便利なのですが、よく忘れるシリーズのトップ3に個人的に入っている組み合わせです。備忘録代わりにここにメモメモ。

これが使えると、たとえば

  • xxxディレクトリ以降から 拡張子が rpm ってなってるファイルを全部 ○○ ディレクトリにコピーする
  • xxxディレクトリ以降の特定のパターンを持つファイルを見つけて、バックアップを取る
  • xxxディレクトリ以降で特定の時間条件(N日前とか)のファイルを見つけて、削除

とかが楽にできるようになります。

使いこなすととても便利。だけど、よく忘れますw

サンプル

以下のように拡張子 go を持つファイルが存在するとします。

$ find . -name "*.go" -type f
./helloworld-go/helloworld.go
./interface_behavior_compare/main.go

これらのファイルを xxx ディレクトリにコピーしたい場合、以下のようになります。

$ mkdir -p xxx

$ ls -l xxx
total 0

$ find . -name "*.go" -type f | xargs -I {} cp {} xxx

$ ls -l xxx
total 8
-rw-r--r-- 1 gitpod gitpod 116 Dec  1 10:14 helloworld.go
-rw-r--r-- 1 gitpod gitpod 595 Dec  1 10:14 main.go

最初慣れていないときに、気持ち悪いのが以下の部分ですよね。

xargs -I {} cp {} xxx

{} って何!?ってなりますw

これ、xargs の -I オプションの後に指定するものなのですが、パイプで渡ってきた元ファイルの場所を置換するためのプレースホルダです。

デフォルトが {} なので、大抵みんな {} ってつけますが、これ何でもいいです。なので、例えば以下のようにしてもオッケイです。

$ find . -name "*.go" -type f | xargs -I {original} cp {original} xxx

ちょっと分かりやすくなるんじゃないでしょうか。私は個人的によく {original} とかにしたりします。

これが出来たら、後は xargs にて実行したいコマンドを好きに変更するだけです。

# 所定の条件を満たしたファイルをバックアップ
$ ls -1 xxx
helloworld.go
main.go

$ find xxx -name "*.go" -type f | xargs -I {original} cp -p {original} {original}.backup

$ ls -1 xxx
helloworld.go
helloworld.go.backup
main.go
main.go.backup


# バックアップファイルを消す
$ ls -1 xxx
helloworld.go
helloworld.go.backup
main.go
main.go.backup

$ find xxx -name "*.backup" -type f | xargs -I {backup} rm -f {backup}

$ ls -1 xxx
helloworld.go
main.go

こんな感じですね。

xargs コマンドの -i オプションは現在非推奨

あと、同じように解説してくださっているページとかで

xargs -i cp {} xxx

というように、-i オプションを利用している記事もたまに見かけますが、-i オプションは現在非推奨となっています。

$ man xargs
・
・
途中割愛
・
・
       -i[replace-str], --replace[=replace-str]
              This option is a synonym for -Ireplace-str if replace-str is specified.  If the replace-str argument is missing, the effect is the same as -I{}.  This option is deprecated; use -I instead.

-I オプションを利用するようにしましょう。


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com