tarファイルのみ、ディレクトリなし


16

ファイルのみを検索するシェルスクリプトを作成し、リストをtarに渡すことができますが、tarに単一のコマンドラインでそれだけを実行できる組み込み機能が既にあるのではないかと考えています。

たとえば、私は--no-recursionスイッチを見つけましたが、私がそうするとき:

tar --no-recursion -cvf mydir.tar mydir

ディレクトリ(サブディレクトリを含む!)内のエントリの名前のみをアーカイブしますが、ファイルはアーカイブしません。

私も試しました:

 tar --no-recursion -cvf mydir.tar mydir/*

ただし、ファイルのみをアーカイブする一方で、サブディレクトリの名前もアーカイブします

ディレクトリだけでなくtarファイルのみを伝える方法はありますか?


5
明確にするために、「フラット」構造(つまり、すべてのファイルが1つのディレクトリに混在する)でアーカイブを作成しますか?
rozcietrzewiacz

1
新しいディレクトリを作成してfind mydir -type f |xargs cp -t tempdirから、tar tempdirを作成できます。
ケビン

@rozcietrzewiaczはい、フラットですが、サブディレクトリからではなく、そのディレクトリからのみです。
ateiob

1
OK、あなたが何をしようとしているのかわかりました。方法find mydir -depth 1 -type f | xargs tar cf mydir.tar
ケビン

2
ああ、スペース。代わりにfindの-execを使用しますfind mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} ++xargsのように同じコマンドライン上に置いて、すべてのファイル。
ケビン

回答:


11

camhが指摘しているように、前のコマンドにはファイル名が多すぎると小さな問題があり、2回以上実行され、後の呼び出しで以前の実行が静かに消去されます。圧縮もしていないので、上書きする代わりに追加できます。

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar Avf mydir.tar
find mydir -maxdepth 1 -type f -exec tar Avf mydir.tar {} +

Iocnarzの答え使用してのtarさん--null-Tのオプションも同様に動作します。cpioインストール済みの場合、それを使用したcamhの回答も問題ありません。またzsh、コマンドに使用しても構いませんが 、zsh glob()を使用したGillesの答え*(.)が最も簡単なようです。


キーは-maxdepthオプションでした。スペースを適切に処理する最終回答:

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar cvf mydir.tar

これも動作するはずです:

find mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} +

4
これらの両方は、の複数の呼び出しをもたらす可能性がありtarます。バリアントとバリアントの両方xargsfindは、+tarに渡すことができる引数の最大数があります。これにより、tarの2回目の呼び出しで、最初の出力が上書きされます。
-camh

2
xargsの制限を拡張すると、xargsはデフォルトで最大128KiBのコマンドラインになります。ファイルリストが大きい場合、コマンド(tar)の2回目(またはそれ以上)の呼び出しが行われ、サイレントデータ損失が発生します。-xデータを失う代わりに、xargsを強制的に失敗させることができます。サイレントデータ損失のバグよりも優れていますが、それでも理想的ではありません。この並べ替えのバグは、最初はすべて問題ないように思えるので非常に危険ですが、ファイルリストが時間とともに大きくなると、トリガーを開始し、バックアップを復元するまで気付かない場合があります。それでは手遅れです。
-camh

@camhそのとおりです、それを指摘してくれてありがとう。それを反映するために更新しました。
ケビン

1
「最終回答」は正しくありません。-Tなしで「tar c」を使用すると、部分的な結果が得られる場合があります。
eckes

14

で使用findするtar場合、最良の方法はのcpio代わりに使用することですtarcpiotarアーカイブを書き込むことができ、stdinからアーカイブするファイルのリストを取得するように設計されています。

find mydir -maxdepth 1 -type f -print0 | cpio -o -H ustar -0 > mydir.tar

使用するfindと、cpioあなたがするようにすることでより多くのUNIX-yのアプローチであるfindことが持っているすべての電源を使用してファイルの選択を行う、と聞かせてcpioアーカイブを行います。この単純な使用法を学ぶ価値はありcpioますtar。試してみると前に突き当たった問題を簡単に解決できます。


鮮やかさ!私は遠い過去にcpioを使用しましたが、ustarオプションを知らなかった。
イアンマッゴーワン

2
これは、受け入れられた答えよりもはるかにうまく機能しました。
デール・アンダーソン

1
ただのニット。-maxdepth 1は-type fの前に来る必要があります。そうしないと、いくつかの検索結果から警告が表示されます
kdubs

ありがとう@kdubs。-maxdepth前に答えを更新しました-type
カム

3

私はあなたの要件を理解しているかわかりません。mydirサブディレクトリではなく通常のファイルを保存する場合、最も簡単な方法はzshを使用することです。通常のファイルに一致するのは、. glob修飾子を使用するだけです:

tar cf mydir.tar mydir/*(.)

3

あなたも使用することができますfind ... -print0し、tar ... --null直接使用することなく、xargsすべてで。

find . -maxdepth 1 -type f -print0 | tar cvf mydir.tar --null -T -

与えられた例では、への--no-recursionオプションtarは必要ありません。なぜなら、ファイルのパスだけが(ディレクトリではなく)からfindに渡されるからtarです。

ただし、次の例で--no-recursionオプションto を使用するとtartarディレクトリを二重にアーカイブできなくなります。findその代わりにディレクトリツリーの再帰をtar行います。

# compare
find . -print0 | tar cf mydir.tar --null -T -
tar -tf mydir.tar | nl

find . -print0 | tar cf mydir.tar --null --no-recursion -T -
tar -tf mydir.tar | nl

2

の序文の段落man tar(最後の文)にあるように、

ディレクトリ名の使用は、常に以下のサブディレクトリをアーカイブに含めることを意味します。

あなたの質問に対する「いいえ」の答えとして理解しています。


タールは今、多くの除外meachismsが含まれていることを除いて良いキャッチ、(例えば--no-recursion--exclude-tagなど)。私は --exclude-tag将来有望に見えますが、私が探しているものの正反対のようです。
ateiob

これを試してみたところ、長いパス名から文字が削除されているのを見ました。camhが提案したように、-Tおよび--nullでtarを使用すると、この問題を回避できました。
ポールブランナン

1
star -c -C startdir -find . ! -type d > out.tar

省略-C startdirして交換.startdir、それがアーカイブに表示されます場合。

これは、libfindの機能に基づいた最も効率的な方法です。Libfindは、-chown -chgrp -chmod構造体のstatを変更し、さまざまなメタデータをアーカイブできるプライマリーも提供します。これはリストおよび抽出モードでも機能し、多くの場合アーカイブ全体を抽出する必要がありません。


あなたは使用することができます-find-copyモード。manページの概要は、次のことができ示唆が、私は(答えしようとしたときに、それを動作させることができていませんでしたフォルダ構造を維持したまま変更されたファイルをコピーする方法(シリー- 2016年2月10日に))
ステファンChazelas

私はこれをもっと長い間テストしませんでした。現在バグがある可能性があります。マニュアルページには、最後の引数は抽出ディレクトリになると書かれていますが、これを試してみると、「抽出モードではまだパス引数がサポートされていません」と表示されます。これは試してみたときに得られるものですか?
schily

はい。manページも、あなただけ-find後に引数を見つける必要がありますが、私は-find I前に、宛先ディレクトリを置く場合も、エラー得ることができます言う
ステファンChazelas

抽出プロセスで検索コードをオフにするコードがあり、エラーメッセージは-cを予期するが、-copyも許可する必要がある誤ったチェックからのものです。-copyモードでは、検索パーサーに最後の引数を含めないでください。
シリー

1
最終的な解決策がsourceforge.net/projects/schilytools/files/schily-2016-03-11.tar.bz2のschilyツールに公開されました。これにより、starのsetlocale()が見つからないことによる問題も修正され、のCディレクトリstar -find
気味悪い

0

私は解決策を見つけたかもしれません。

find mydir -type f -printf '%P\0'|tar czvf mydir.tar.gz -C mydir --null -T -

これは少しコストがかかるかもしれませんが、とにかく動作します。これはxargsに依存しないためです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.