フラミナル

1日1記事を目標にITのことについて書くブログ

findとtarを組み合わせ 大量ファイルを一気にまとめる

Find

find . -name xxx print0 | xargs --null  tar cvfpz test.tar.gz

こんなコマンドを実行するとカレント配下のxxxのファイルをごっそり集めて、test.tar.gzを作成することができます。

-print0
              真 を返す。ファイル名をフルパスで標準出力に表示し、各ファイル名にヌル文字を付加する。このオプション
              を用いれば、 find の出力を処理するプログラムにおいて改行文字を含んだファイル名を正しく解釈できる よ
              うになる。
--null, -0
              標準入力からの文字列の区切りに、空白ではなくヌル文字が使われているとみなす。また引用符やバックス ラ
              ッ シュに特別の意味を持たせず、すべての文字をそのまま用いる。ファイル終了文字列も無効となり、他の文
              字列と同じように扱われる。入力される文字列に空白・引用符・バックスラッシュが含まれている場合に有 用
              で あろう。 GNU find の -print0 オプションの出力を、このオプションを指定した xargs の入力とすると良
              い。

しかしこの時、注意しないといけないことが。

問題点

xargsはfindの標準出力をtarの引数に渡してくれるコマンドですが、findの結果によってはxargsが使用できるバッファ領域をあふれてしまうため複数回にコマンドが分けて実行されます。

すると同じ名前のtarファイルを作成すると、複数回行うたびにファイルがオーバーライドされてしまうために最後のデータしか残らないのです。

これを回避するには2種類のやり方があります。

回避策

その1(-sを使う方法)

xargs -s xxxxxをつかってxargsのバッファ領域を増やす

 find . -name xxx -print0 | xargs -s 500000 --null tar cvfpz test.tar.gz
-s max-chars
              1 コマンドラインにつき最大 max-chars の文字を使用する。 この文字数には、指定したコマンドと initial-argu‐
              ments、それに 各引き数文字列の終端を示すヌル文字も含まれる。指定できる値の上限は システム次第であり、ex‐
              ec    に対する引き数の最大長から、    現在の環境のサイズと   2048   バイトの余裕領域を引いたものである。
              もしその値が    128KiB    以上だったときは、デフォルトの値として    128KiB     が     使用される。128KiB
              未満だったときは、算出された上限がデフォルトの値になる。 1KiB は 1024 バイトである。

こんな感じですね。

その2(nullで切り分ける方法)

find . -name xxx print0 | tar cvfpz test.tar.gz -T - --null 

tarコマンドの-Tオプションで抽出するファイルの一覧をファイルから取れるようにします。さらに後ろの-が標準入力を示しています。

よってこれらを組み合わせて実行するわけです。

使いやすい方をつかってみてください。