SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

業務でラクするためのUNIXテクニック集

find/grep/xargsコマンドを使いこなす
業務で楽するためのUNIXテクニック集「検索」編

第1回


  • X ポスト
  • このエントリーをはてなブックマークに追加

検索結果に対するコマンドの実行(find -exec/xargsコマンド)

 検索して見つかった全ファイルを一度に処理したい場合、findコマンドのアクションを利用して次のように指定できます。

$ find . -type f -exec コマンド '{}' \;

 「-exec」アクションにより、検索結果に対して「コマンド」を実行します。このとき「{}」がfindコマンドの実行結果、つまりファイルのパスに置き換えられます。「'{}'」のシングルクォートは、シェルの予約語として解釈されるのを避けるために付けています。

 ただし上記の例は、ファイル数分「コマンド」が実行されるので時間がかかります。このため、一般的にはxargsコマンドを用いて、次のように指定します(Solarisには対応していません)。

$ find . -type f -print0 | xargs -0 コマンド

 xargsコマンドは、標準入力から引数を読み込み、指定の「コマンド」を実行します。上記の例では、findコマンドを利用して見つかった全ファイルのパスを、一度に「コマンド」へ渡しています。

 なお、空白や特殊文字を含むファイルを正しく処理するため、findコマンドには必ず「-print0」オプションを付け「xargs -0」で受け取るようにしましょう。「-0」オプションは「--null」でも構いません(FreeBSDでは「-0」オプションのみ利用可能)。

 これにより、findコマンドは空白と改行ではなくヌル文字(\0)を区切りとして、検索結果を出力します。同様にxargsコマンドも、引数がヌル文字で区切られているものとして処理を行います。

※注2

 findコマンドの-execアクションは、シェルを起動しません。シェルコマンドを使いたい場合は、次のように指定します。

$ find … -exec bash -c 'シェルコマンド文字列' \;
※注3

 xargsコマンドで一度に渡せる長さの制限はOSによって異なります。制限値は「ARG_MAX」というマクロ定数で定義されています。Debian の場合は、次のコマンドで自分の使っているOSのARG_MAXを調べることができます。

Debian の場合のARG_MAX調査方法
$ getconf ARG_MAX
131072

 最近のfindコマンド(GNU findの4.2.12以降)では、見つかったファイルを一度に処理するための「-exec コマンド '{}' +」オプションが存在します(FreeBSD、Solarisも対応)。

$ find . -type f -exec コマンド '{}' +

 「+」を指定した場合、「{}」が、検索して見つかった全ファイル名のパスに置き換えられます。

 xargsコマンドを使わない場合は、シェルの制御構文を使って次のように指定できます。

$ find . -type f -print0 | while read -r -d '' file; do コマンド "$file"; done

 ファイル名に「\(バックスラッシュ)」が含まれている場合に備え、readに「-r」オプションを付けています。ただし、この方法も見つかったファイル数分「コマンド」を実行するので、速度は遅くなります。

例)上記のそれぞれの方法で、検索して見つかったファイルに対しlsコマンドを用いて一覧表示
$ ls
test1.txt       test2.txt       test3.txt

$ find . -type f -exec ls '{}' \;
./test1.txt
./test2.txt
./test3.txt

$ find . -type f -print0 | xargs -0 ls
./test1.txt ./test2.txt ./test3.txt

$ find . -type f -exec ls '{}' +
./test1.txt ./test2.txt ./test3.txt

$ find . -type f -print0 | while read -r -d '' file; do ls "$file"; done
./test1.txt
./test2.txt
./test3.txt

 このようにコマンドの組み合わせによって、「ファイル名のグループを一度にlsコマンドで実行」か「ファイル数分lsコマンドを実行」するかが異なり、処理速度が変わってきます。

次のページ
findコマンドを利用した便利なUNIXテクニック例

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
業務でラクするためのUNIXテクニック集連載記事一覧

もっと読む

この記事の著者

保田和隆(ヤスダカズタカ)

Yasuda Kazutakaネットワーク関連の組み込みソフトウェア開発者。http://uguisu.skr.jp/Windows/

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3279 2008/12/22 16:25

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング