tar: --exclude를 사용하여 압축을 풀면 너무 욕심이 많습니다. 루트 수준 파일만 제외하는 방법은 무엇입니까?

tar: --exclude를 사용하여 압축을 풀면 너무 욕심이 많습니다. 루트 수준 파일만 제외하는 방법은 무엇입니까?

저는 맥, 엘 캐피탄을 사용하고 있습니다.

내 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}

또는 두 번째 옵션을 사용하여 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-

여기서 -print0to find--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'

관련 정보