web-dev-qa-db-ja.com

「tar」コマンドと「find」を組み合わせる方法

Findコマンドはこの出力を提供します:

 [root @ localhost /]#find var/log/-iname anaconda。* 
 var/log/anaconda.log 
 var/log/anaconda.xlog 
 var/log/anaconda.yum.log 
 var/log/anaconda.syslog 
 var/log/anaconda.program.log 
 var/log/anaconda.storage.log 

Tarと組み合わせると、次の出力が表示されます。

 [root @ localhost /]#find var/log/-iname anaconda。* -exec tar -cvf file.tar {} \; 
 var/log/anaconda.log 
 var/log/anaconda.xlog 
 var/log/anaconda.yum.log 
 var/log/anaconda.syslog 
 var/log/anaconda.program.log 
 var/log/anaconda.storage.log 

しかし、tarファイルを一覧表示すると、単一のファイルのみが表示されます

 [root @ localhost /]#tar -tvf file.tar 
-rw ------- root/root 208454 2012-02-27 12:01 var/log/anaconda。 storage.log 

ここで何が間違っているのですか?

Xargsを使用すると、次の出力が得られます。

[root @ localhost /]#find var/log/-iname anaconda。* | xargs tar -cvf file1.tar

二番目の質問

Varの前に/と入力すると、find /var/logがこのメッセージを表示する理由tar:先頭の削除メンバー名からの `/ '

 [root @ localhost /]#find/var/log/-iname anaconda。* -exec tar -cvf file.tar {} \; 
 tar:メンバー名から先頭の「/」を削除
/var/log/anaconda.log 
 tar:メンバー名から先頭の「/」を削除します
/var/log/anaconda.xlog 
 tar:先頭を削除しますメンバー名からの `/'
/var/log/anaconda.yum.log
tar:メンバー名からの先頭の`/'の削除
/var/log/anaconda.syslog 
 tar:メンバー名から先頭の「/」を削除します
/var/log/anaconda.program.log 
 tar:メンバー名から先頭の「/」を削除します
/var/log/anaconda.storage.log 

単純な形で、次の2つの違いは何ですか?

find var/logおよびfind /var/log

33
max

あなたは次のようなものを使うことができます:

find var/log -iname 'anaconda.*' -print0 | tar -cvf somefile.tar --null -T -

-print0および-T連携して、スペース改行などのファイル名を許可します。最後の-は、入力ファイル名をstdinから読み取るようにtarに指示します。

ご了承ください -print0この答え に従って、ステートメントの最後に来る必要があります。そうしないと、おそらく予想よりも多くのファイルが取得されます。

44
user35787

これを試して:

_tar -cvf file.tar `find var/log/ -iname "anaconda.*"`
_

findを_-exec tar_に使用しようとしました。しかし、_-exec_オプションが機能する方法では、一致するファイルが見つかるたびにそのコマンドが1回実行され、tarが毎回生成するtarファイルを上書きします。あなたが最後のものだけで終わったのはそのためです。また、シェルがfindに渡す前に展開しないように、findに指定するパターンを引用符で囲む必要があります。

バッククォートを使用したコマンド置換(または、必要に応じて$(...)表記を使用)を使用すると、findによって生成された名前のリスト全体が、tarの引数としてコマンドラインに貼り付けられます。 、それらを一度にすべて書き込みます。

12
Nicole Hamilton

質問1

tarは見つかった各ファイルを取得してfile.tarにアーカイブしているため、コマンドは失敗します。そのたびに、以前に作成されたfile.tarを上書きします。

すべてのファイルを含む1つのアーカイブが必要な場合は、tarを直接実行するだけです。findは必要ありません(名前にスペースが含まれているファイルでも機能します)。

tar -vcf file.tar /var/log/anaconda*   

質問2

2つのコマンドは完全に異なります。

  • find var/logはvar/logというディレクトリを検索しますこれは現在のディレクトリのサブディレクトリです、これはfind ./var/logと同等です(./に注意してください)。

  • find/var/logは、/var/logルートのサブディレクトリである/というディレクトリを検索します。

先頭の/メッセージはtarではなくfindからのものです。これは、ファイル名の最初の/を削除して絶対パスを相対にすることを意味します。つまり、アーカイブを解凍すると、/var/log/anaconda.errorのファイルが./var/log/anaconda.errorに抽出されます。

6
terdon

2つの方法があります-exec 働ける。 1つの方法でコマンドを何度も実行します-ファイルごとに1回。もう1つの方法では、すべてのファイルをパラメーターのリストとして含めて、コマンドを1回実行します。

  • -exec tar -cvf file.tar {} ';'は、各ファイルに対してtarコマンドを実行し、毎回アーカイブを上書きします。
  • -exec tar -cvf file.tar {} '+'tarコマンドを1回実行し、見つかったすべてのファイルのアーカイブを作成します。
2
mwfearnley

各ファイルに-execを使用すると、多くのファイルがある場合、tar圧縮が非常に遅くなる可能性があると思います。私は次のコマンドを使用することを好みます:

find . -iname "*.jpg" | cpio -ov -H tar -F jpgs.tar
1
fabceolin