tar:--excludeを使用して解凍すると、あまりにも欲張りです。ルートレベルのファイルのみを除外する方法は?

tar:--excludeを使用して解凍すると、あまりにも欲張りです。ルートレベルのファイルのみを除外する方法は?

私はMac、El Capitanを使用しています。

私のzipファイル構造:

README.md
source/README.md

ディレクトリの--excludeルートレベルを除いては動作しないようです。README.mdsource

私は次のようなさまざまなバリエーションを試しました。

# Doesn’t exclude anything:
tar -xf master.zip --strip-components 1 --exclude=/README.md
tar -xf master.zip --strip-components 1 --exclude=/{install.sh,README.md}

# Excludes both files:
tar -xf master.zip --strip-components 1 --exclude=./README.md
tar -xf master.zip --strip-components 1 --exclude={install.sh,README.md}
tar -xf master.zip --strip-components 1 --exclude=./{install.sh,README.md}

質問:

どうすれば除外できますか?ただルートレベルREADME.md

答え1

実際、tarは次のファイルを除外できます。--anchored

パターン一致ファイル名の開始

ただし、完全なファイルパスを作成する必要があります(したがってパスも変更されますcd)。

$ cd /where/source/lives
$ tar -cf master.zip --anchored --exclude={source/install.sh,README.md} -- *

柔軟性が必要な場合はfindを使用してください。このコマンドを使用して、基本ファイルを拒否し、圧縮する
ファイルのリストを生成できます。
! -name README.mdREADME.md

$ path="/path/to/files"
$ find "$path/" ! -path  "$path"/README.md -print

スラッシュに注意してください/。本当に重要です。圧縮する正しいファイルのリストが含まれている場合は、それを挿入するだけですtar(追加0および-print生成tarコマンド)。

find "$path/" ! -path  "$path"/README.md -print0 |
tar --no-recursion --null -T- --exclude=install.sh -v -cf master.zip

オプションは一致するために使用さtarれます。--null-print0find

find必要なすべての再帰が提供されますので、tarのオプションを使用してください--no-recursion

また、ファイルはinstall.shまだ除外されていますtar(削除された可能性がありますが、findこれは個人的な好みにすぎません)。

本番環境では、-vよりきれいなtarコマンドのためにこのオプションを削除してください。


解凍するには(上記のように圧縮するのではなく)、次のコマンドを使用します。

tar -xf master.zip --anchored --exclude={source/install.sh,README.md}

または、2番目のオプションを使用してzipファイルを生成すると、除外されたファイルは内部に含まれません。master.zip実行する必要がある作業は次のとおりです。

tar -xf master.zip    

答え2

誰かがより良い答えを出すことができますが、tarの--excludeオプションで問題が解決しない場合は、それを使用してfindファイルのリストを作成してそれに供給できますtar

find * -path README.md -prune -o -print | 
tar --no-recursion -cf /tmp/data.tar -T-

これは、最上位レベルではないすべてのファイル(およびディレクトリ)のリストを印刷してREADME.mdから提供し、はtar(使用)からそのファイルのリストを読み取ります。それ以外の場合は、ディレクトリ内のすべてのファイルが自動的に含まれるため、このフラグが必要です。それ以外の場合、そのファイルも作成され、アーカイブに同じ名前の複数のファイルがあるため、望ましくありません。stdin-T---no-recursiontarfind

より強力なバージョンは次のとおりです。

find * -path README.md -prune -o -print0 | 
tar --no-recursion -cf /tmp/data.tar --null -T-

ここで、 -print0tofind--nulltoはtar、ファイル名がスペースの代わりにASCII NUL文字で区切られていることを示します。これは、パイプがスペースを含むファイル名を処理することを意味します。

答え3

これpaxこのユーティリティには、BSD tar よりも広範な除外機能があります。この-sオプションを使用すると、名前を保存または検索するときに名前を変換でき、名前が空の文字列に変換されるとファイルは除外されます。

(BSD tarにはかなり似た-sオプションがありますが、ドキュメントによるとnull-exclude機能がないようです。)

zcat foo.tar.gz | pax -r -pe -s'!^README\.md$!!' -s'!^\./README\.md$!!'

(おそらく圧縮された)tarファイルを想定していることに注意してください。 zipファイルがある場合は、以下を使用してください。unzip代わりに。

unzip foo.zip -x 'README.md'

関連情報