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를 사용하여 공용 기본 폴더를 만드는 방법과 폴더 이름을 바꾸는 방법은 무엇입니까?- 자매사이트에서 우분투에 대해 물어보세요.

답변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이것은 많은 경우에 좋은 기능이지만 약간 다른 아카이브 구조를 제공하므로 우리가 통제할 수 없을 때 압축 풀기 끝이 깨질 수 있습니다.

관련 정보