tarアーカイブのファイルの前にディレクトリを追加するには?

tarアーカイブのファイルの前にディレクトリを追加するには?

ファイルをtarアーカイブfooに圧縮したいのですが、アーカイブにディレクトリとして表示したいです。したがって、どこかに解凍するとファイルが 。bararchive.tarbazdirbazdirfoobar

どうすればいいですか?

これは次の逆になります。

https://stackoverflow.com/questions/939982/how-do-i-tar-a-directory-of-files-and-folders-without-include-the-directory-it
または
フラットtarアーカイブの作成:フォルダを追加したときにすべての親アイテムを無視する

答え1

このオプションを使用できます--transform。たとえば、

touch foo bar
tar cf archive.tar foo bar --transform 's,^,bazdir/,'
tar tvf archive.tar 
-rw-r--r-- tigger/tigger     0 2017-10-11 19:32 bazdir/foo
-rw-r--r-- tigger/tigger     0 2017-10-11 19:32 bazdir/bar

詳細とより複雑なオプションについては、以下を参照してください。tarを使用してパブリックデフォルトフォルダを作成する方法とフォルダ名を変更する方法は?- 姉妹サイトでUbuntuについて尋ねてください。

答え2

macOSを使用している場合は、-s代わりにオプションを使用してください--transform

-sモード

パターンに従ってファイルまたはアーカイブメンバー名を変更します。このパターンの形式は/old/new/[ghHprRsS]です。ここで、oldはデフォルトの正規表現、newは一致する部分の代替文字列、オプションの末尾の文字は置換の処理方法を変更します。以前のパターンが一致しない場合は、パターンをスキップします。新しい場合、〜は一致に置き換えられます...

オプションの末尾の p は、置換が成功した後に元のパス名と新しいパス名が標準エラーに出力されることを指定します。

上記の情報に基づいて、-s次のようにオプションを定義できます。

$ tar -c -a -v -s "|.*|prefix/~|p" -f ../out.tar.gz 1.txt 2.txt N.txt

1.txt >> prefix/1.txt
a prefix/1.txt
2.txt >> prefix/2.txt
a prefix/2.txt

どこ

  • |- デフォルトの「/」ではなくパターン部分区切り記号です。
  • .*- パターンの「前」部分(すべての項目と一致)を定義する正規表現。
  • prefix/~- "old" 部分 ("~" で定義される) の前に追加された表現です。
  • p- アーカイブするファイルの元の名前と新しい名前を印刷するモードオプション。

実際のケース - gitリポジトリのすべてのファイルを保持します(サブモジュールを含む):

$ git ls-files --recurse-submodules | tar -c -a -v --files-from - -s "|.*|1.0.2/~|" --file "dist_1.0.2.tar.gz"

a 1.0.2/.gitignore
a 1.0.2/.gitmodules
a 1.0.2/.prettierignore
a 1.0.2/.prettierrc
a 1.0.2/.vscode/settings.json
a 1.0.2/Gulpfile.mjs
a 1.0.2/Ports.mjs
a 1.0.2/Readme.md
a 1.0.2/Version.cjs
a 1.0.2/app.mjs
a 1.0.2/app.test.mjs
a 1.0.2/jest-fastify-env.mjs
a 1.0.2/jest.babel.config.cjs
a 1.0.2/jest.config.mjs
a 1.0.2/jest.setup.mjs
a 1.0.2/lib/conf/Stack.mjs
a 1.0.2/lib/shared/.gitignore
a 1.0.2/lib/shared/AWSS3Client.cjs
a 1.0.2/lib/shared/Api.cjs
a 1.0.2/lib/shared/Api.test.mjs
a 1.0.2/lib/shared/AppConfig.cjs
a 1.0.2/lib/shared/DBApi.cjs
a 1.0.2/lib/shared/DBClient.cjs
a 1.0.2/lib/shared/DBExporter.mjs
a 1.0.2/lib/shared/DynamoDBClient.cjs
a 1.0.2/lib/shared/DynamoDBConnection.cjs
a 1.0.2/lib/shared/RDS.mjs
a 1.0.2/lib/shared/RDSClient.mjs
a 1.0.2/lib/shared/SecuredApi.cjs
a 1.0.2/lib/shared/SecuredApi.test.mjs
a 1.0.2/lib/shared/SecuredApiErrorIds.cjs
a 1.0.2/lib/shared/SharedEnv.cjs
a 1.0.2/lib/shared/conf/AppEnv.cjs
a 1.0.2/lib/shared/helpers/CognitoTokenDownloader.cjs
a 1.0.2/lib/shared/helpers/CognitoTokenDownloader.test.mjs
a 1.0.2/lib/shared/helpers/HTTPAuthHelper.cjs
a 1.0.2/lib/shared/helpers/HTTPAuthHelper.test.mjs
a 1.0.2/lib/shared/helpers/Preprocessor.cjs
a 1.0.2/lib/shared/helpers/Preprocessor.test.mjs
a 1.0.2/lib/shared/helpers/TokenVerifier.cjs
a 1.0.2/lib/shared/helpers/TokenVerifier.test.mjs
a 1.0.2/lib/shared/helpers/TokenVerifierErrorIds.cjs
a 1.0.2/lib/shared/helpers/TypeChecking.cjs
a 1.0.2/lib/shared/helpers/TypeChecking.test.mjs
a 1.0.2/lib/shared/testability/TokenFixture.cjs
a 1.0.2/lib/shared/types/CustomDateFormatter.cjs
a 1.0.2/lib/shared/types/CustomDateFormatter.test.mjs
a 1.0.2/lib/shared/types/EnvName.cjs
a 1.0.2/lib/shared/types/GenericError.cjs
a 1.0.2/package.json
a 1.0.2/scripts/shared/.gitignore
a 1.0.2/scripts/shared/Prompt.cjs
a 1.0.2/scripts/shared/VersionTool.mjs
a 1.0.2/server.mjs
a 1.0.2/yarn.lock

macOSのFinder.appで「dist_1.0.2.tar.gz」をダブルクリックすると、すべてのアーカイブファイルを含む「1.0.2」というフォルダが表示されます。

答え3

現在のディレクトリに存在しないと仮定すると、bazdir最も直接的な方法は次のとおりです。

$ ln -s . bazdir
$ tar cvf myfile.tar bazdir/{foo,bar}
a bazdir/foo
a bazdir/bar

.tarファイルを作成した後、bazdirシンボリックリンクを削除します。

$ rm bazdir

ファイル.tarには次のディレクトリプレフィックスが含まれますbazdir/

$ tar tvf myfile.tar 
-rw-------  0 jim    wheel       0 Dec 11 13:41 bazdir/foo
-rw-------  0 jim    wheel       0 Dec 11 13:41 bazdir/bar

tarファイルを抽出すると、bazdir実際のディレクトリが作成されます。

$ tar xvf myfile.tar 
x bazdir/foo
x bazdir/bar
$ find .
.
./myfile.tar
./foo
./bazdir
./bazdir/bar
./bazdir/foo
./bar
$ file bazdir
bazdir: directory

ソースディレクトリに触れたくない場合(または実際に読み取り専用の場合)、シンボリックリンクを別の場所に配置できます。

$ ln -s $(pwd) /tmp/bazdir
$ tar cvf /tmp/myfile.tar -C /tmp bazdir/{foo,bar}
a bazdir/foo
a bazdir/bar
$ rm /tmp/bazdir
$ tar tvf /tmp/myfile.tar 
-rw-------  0 jim    wheel       0 Dec 11 13:41 bazdir/foo
-rw-------  0 jim    wheel       0 Dec 11 13:41 bazdir/bar

答え4

非常に効率的ではありませんが、明確な方法はrsyncファイルを一時ディレクトリに保存してから保存することですtar

--transformこれは多くの場合に良い機能ですが、少し異なるアーカイブ構造を提供しているため、制御できない場合に解凍端が壊れる可能性があります。

関連情報