非常に大きなtar.gzアーカイブから複数のディレクトリ(例えば、、、aaa
)bbb
を抽出したいと思いますccc
。
ccc
ある時もありない時もありますが、抽出過程で失敗することがないようにしたいと思います。
tarアーカイブからディレクトリの一部が存在しない場合でも、失敗せずに正確なディレクトリのリストを抽出できますか?
tar -xzf file.tar.gx --wildcards aaa bbb ccc
アーカイブに場所がない場合、コマンドは失敗します。
答え1
pax
1つのオプションは、標準コマンドを使用してtarアーカイブを抽出し、この-'s/regexp/replacement/
オプションを使用して選択項目から不要なメンバーを削除することです。
<file.tar.gz gunzip |
pax '-s:'{aaa,bbb,ccc}':&:' \
'-s:.*::' -r
パスにaaa
、bbb
またはを含むすべてのアーカイブメンバーに対してccc
同じメンバーに置き換えるので、何もできませんが、一致するものがある場合は、次の置換をスキップし、特にs:.*::
アーカイブメンバーを削除する効果があります。
抽出する項目を確認するには-r
。フラグを削除して交換に追加して、p
どの交換が行われているかを報告できます。
pax
少なくともDebian / UbuntuのMirBSD実装は、シンボリックリンクのアーカイブメンバーがある場合、シンボリックリンクのターゲットがパターンと一致しない場合(パスが一致していても)、そのメンバーが削除されることを発見しました。バラよりhttps://austingroupbugs.net/view.php?id=1618現在、この分野のAPIを改善するための議論が進行中です。
答え2
tar
私が知っている限り、GNUおよびBSDコマンドはそれをサポートしていませんが、次のようになります。
アーカイブが十分に小さい場合、またはメディアから読み取れない場合は、巻き戻しのtar
費用がかかります(実際テープアーカイブ)list_of_matching_files=$(tar -tf file.tar.gz | grep '(aaa|bbb|ccc)')
ファイルのリストをコンパイルできます。ファイル名に改行文字が含まれている場合、何が起こるのか気にしません。これは完全に合法的です。
tar
したがって、これは実行されるすべてのファイルに対してコマンドを実行するためにこのオプションを使用できるオプションを(少なくともGNUでは)提供します--to-command=
。パイプで接続されたデータを適切な名前のファイルに書き込むか、単に無視するかを選択するためにプログラムで使用できる環境変数がtar
設定されます。次に、ファイル/ディレクトリの種類、所有者、モード、および日付を適切に処理するために異なる環境変数を設定するTAR_REALNAME
必要があります。TAR_**
簡単に言えば、(やや愚かな)形式を読むのではなく、独自のプログラム/シェルスクリプトで作業を実行.tar
できます。tar
あるいは正直なところ、tarはとにかく順番に読み取られなければならず、保存スペースは一般的に安いので、すべてを抽出し、抽出されたファイルを書き留めて「間違った」ファイルを削除するだけです。
7z
または、パターンが一致しない場合にtarファイルの抽出も中断されることを確認することをお勧めします。
最後に、すべての適切なプログラミング言語にはtar
消費ライブラリがあります。実際にはPythonの6行の価値があるかもしれません。 2行目を参照してください。はい公式文書から:
#!/usr/bin/env python3
import os
import tarfile
def py_files(members):
for tarinfo in members:
"""
modify this check: only `yield tarinfo` if the
tarinfo.name matches your needs. Conveniently,
python has string functions like `tarinfo.name.startswith("foo")`
and a capable regex library
"""
if os.path.splitext(tarinfo.name)[1] == ".py":
yield tarinfo
tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()
答え3
エラーに関係なく、tar
他のファイルが抽出されます。エラーに興味がない場合は無視してください。戻りコードをテストせずstderr
に送信しました。/dev/null
$?
tar -xzf file.tar.gz files 2> /dev/null
コマンドを順番に実行する必要がある場合は、;
代わりにを使用してください&&
。
tar ... ; ...