매우 큰 tar.gz 아카이브에서 여러 디렉토리(예: aaa
, bbb
, )를 추출하고 싶습니다 ccc
.
ccc
있을 때도 있고 없을 때도 있지만 추출 과정에서 실패하는 일이 없도록 하고 싶습니다.
tar 아카이브에서 디렉토리 중 일부가 존재하지 않는 경우에도 실패하지 않고 정확한 디렉토리 목록을 추출할 수 있습니까?
tar -xzf file.tar.gx --wildcards aaa bbb ccc
아카이브에 위치가 없으면 명령이 실패합니다.
답변1
pax
한 가지 옵션은 표준 명령을 사용하여 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 여섯 줄의 가치가 있을 수 있습니다. 두 번째 줄을 참조하세요.예공식 문서에서:
#!/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 ... ; ...