tarred 파일의 내용을 추출하지 않고 내용을 보려고합니다. 시나리오 : a.tar가 있고 그 안에 파일이 ./x/y.txt
있습니다. y.txt
실제로를 추출하지 않고 의 내용을보고 싶습니다 a.tar
.
tarred 파일의 내용을 추출하지 않고 내용을 보려고합니다. 시나리오 : a.tar가 있고 그 안에 파일이 ./x/y.txt
있습니다. y.txt
실제로를 추출하지 않고 의 내용을보고 싶습니다 a.tar
.
답변:
그것은 아마 GNU의 특정 옵션,하지만 당신은 사용할 수 -O
또는 --to-stdout
표준 출력에 추출물에 파일을
$ tar -axf file.tgz foo/bar -O
tar -axf file.tar.gz --wildcards --no-anchored '*read_this_file*' --O
예를 들어, 많은 파일이 일치 *read_this_file*
합니다. 모든 것이 같은 줄에 인쇄됩니다. 에서 man
찾았습니다 --to-command
. Passing --to-command="echo '' && cat"
은 약간의 흑 마법이지만 작동합니다 : D
$ tar -axf file.tgz foo/bar -O
./x/y.txt의 내용을 a.tar에서 STDOUT으로 인쇄합니다.
tar xfO a.tar ./x/y.txt
이것은 간단합니다
less a.tar:./x/y.txt
이 마술의 트릭은 당신이 경우 작동 lesspipe
설치되어있는 경우는 ENV 변수 LESSOPEN
로 정의된다 | /usr/bin/lesspipe.sh %s
당신이있는 경우에 예상되는 lesspipe가 제대로 설치.
lesspipe.sh
선호되어야합니다.
아, 그러나 이것은 파일 내의 파일 내용에 관한 질문 tar
입니다. 실제로 어떤 경우에는 그렇게 어렵지 않습니다. 문제는 tar
파일이 차단 된 스트림 파일 일뿐입니다. 아카이브 내의 각 파일은 그 이전의 파일 이후에 발견되며 각 파일은 지정된 형식 에 따라 메타 데이터 헤더 를 가져옵니다 .
이 형식을 기반으로 한 번 작성했습니다 shitar
. 이것은 몇 줄의 dd
셸 스크립트 tar
였으며 즉시 블록 장치 스트림 을 만들 수있었습니다 . 동일하게, 더 최근에는 다음 과 같은 몇 줄의 코드를 작성했습니다 .
tar --no-recursion -c ./ |
{ printf \\0; tr -s \\0; } |
cut -d '' -f-2,13 |
tr '\0\n' '\n\t'
... tar
파일을 즉시 분리 하고 구성 요소 텍스트 파일에서 인라인 변환을 수행합니다. 이 cut
필드 는 NUL로 구분 된 입력 라인 의 필드 1,2,13 을 가리 킵니다 . 512 바이트마다 한 번씩 발생할 수있는 레코드 구분 기호 를 단 하나의 NUL로 압축하고 제거 할 수 있기 때문에 파일에 텍스트 파일 만 포함되어 있으면 이러한 작업이 쉬워 집니다.tar
tar
tar
헤더 형식은 다음과 같습니다.
field offset len
name 0 100
mode 100 8
uid 108 8
gid 116 8
size 124 12
mtime 136 12
chksum 148 8
typeflag 156 1
linkname 157 100
magic 257 6
version 263 2
uname 265 32
gname 297 32
devmajor 329 8
devminor 337 8
prefix 345 155
tar
아카이브 형식의 훨씬 더 복잡한 측면으로 간단한 조작 을 처리하는 상대적 용이성 사이에 급격한 기울기가 있음을 이해 하십시오. 작은 유형의 파일을 함께 묶거나 예측할 수있는 유형의 멤버 만 포함 된 아카이브를 분할하는 것과 같은 간단한 작업은 몇 개의 쉘 파이프로 쉽게 수행 할 수 있지만 임의의 아카이브 멤버를 안정적으로 처리하는 것은 쉬운 일이 아닙니다.
이러한 멤버가 임의의 이진 데이터를 포함하는 경우 특히 어렵습니다. 신뢰할 수있는 응용 프로그램을 확실히 배제 할 수 있습니다. tr -s
이 어려움은 기본 및 / 또는 문자 세트 이외 의 다양한 유형의 파일이 네이티브 및 / 또는 문자 세트 이외의 파일을 사용하는 경우에만 복잡 합니다. 원본 보관 파일은 처리 할 준비가되지 않은 형식 응용 프로그램 특이성을 사용하여 구현되었습니다. 그리고 이것은 tar
아카이브 유형 의 기본적이고 표준화 된 측면에 대해서만 다루고 있습니다. 확장 헤더 추가 및 확장명 확장 및 스파 스 파일 및 압축 및 ... 음, 행운을 빕니다.
기본으로 돌아가서 아카이브 의 표준 레코드 크기 tar
는 20 블록 또는 10240 바이트입니다. 그러나 표준 레코드 크기로 차단되고 표준 파일 형식과 표준 ustar
헤더 만 포함 된 아카이브를 고려할 때 size
헤더 필드 에 따라 읽기를 수행하여 멤버 헤더와 멤버 헤더 간을 건너 뛰어야 합니다. 당신이 찾는. 거기에 size
도달하면 대상 멤버 헤더의 꼬리에서 시작하여 오프셋 에서 바이트 단위로 읽습니다 . 그리고 그것은 당신의 파일입니다.
그러나 헤더를 건너 뛰기는 쉽지 않습니다. 다른 유형은에 해당하는 실제 데이터 블록이 추가되거나 추가되지 않습니다 size
. 예를 들어, 디렉토리 및 링크에는 이러한 데이터 블록이없고 헤더 설명 만 포함되므로 size
필드를 건너 뛰기 수식에 적용해야하는지 여부를 정확하게 확인하기 전에 현재 헤더의 파일 유형을 확인할 준비가되어 있어야합니다 .
또한 아카이브 멤버의 크기가 10240 표준 레코드 크기 와 잘 동기화되는지 여부에 따라 레코드 크기 요소 에 각각 0 블록이 추가되거나 추가되지 않을 수 있습니다. 그리고 레코드 크기는 아카이브 생성시 선언 될 수 있으므로 20 블록이 될 수는 없지만 사양에 따라 항상 512 바이트 단위로 차단되어야합니다.
tar
교환 형식; 확장 설명 섹션을 참조하십시오 . 문자 특수 아카이브 파일에 대한이 형식 의 기본 블록 크기 는 10240 입니다. 구현 은 512의 배수 인 32256 보다 작거나 같은 모든 블록 크기 값을 지원해야합니다 .따라서 tar
임의의 이진 데이터를 포함 할 수있는 파일을 포함 할 수있는 파일 로 작업하는 경우 파일 형식에 따라 알고리즘을 통해 파일을 건너 뛰어야합니다. 사양은 말합니다 :
size
필드는 옥텟에서 파일의 크기입니다.
typeflag
필드 형으로 파일에 설정되어 1 (a 링크 ) 또는 2 (a 심볼릭 링크 ) 의 size
필드는 0으로 지정된다.typeflag
필드 형식의 파일을 지정하는 설정 5 ( 디렉토리 ) 의 size
해당 레코드 유형의 정의에 설명 된대로 필드 해석된다.typeflag
필드에 설정된 3 ( 문자 특별 파일) , 4 ( 특수 블록 파일) 또는 (6) ( FIFO가 ) 상기의 의미 size
필드는 POSIX.1-2008의 부피로 지정하고, 데이터가 논리 레코드 수 없다 매체에 저장됩니다.size
읽을 때 필드는 무시해야한다.typeflag
필드가 다른 값으로 설정 되면, 나눗셈 결과의 일부를 무시하고 헤더 다음에 기록 된 논리 레코드의 수는 입니다.( (
size
+ 511 ) / 512 )
... 물론 각 헤더의 개별 크기도 고려합니다. 이는 회원 당 추가 블록입니다. 따라서 원하는 헤더와 일치하는 헤더에 도달 할 때까지 헤더에서 헤더로 읽기를 건너 뛸 수 있습니다. 그러면 현재 레코드가 단순히 파일 또는 실제 파일에 대한 링크 를 설명하는지 여부를 확인해야 합니다 . 동일한 파일이 여러 번 아카이브에 추가 될 때 실제 파일의 데이터가 아카이브의 다른 곳에서 이미 발견 될 수 있기 때문에 많은 파일에 링크 헤더 tar
만 포함 되기 때문에 이는 특히 중요 합니다.
chksum
필드에 계산을 적용 하고 원하는 파일이 실제로 원하는 파일인지 확인해야합니다. tar
의는 chksum
매우 간단 though-입니다 :
chksum
헤더 논리 레코드의 모든 옥텟의 단순 합계 8 진수 값 1991 표준 IRV 표현 : 필드는 ISO / IEC 646이어야한다. 헤더의 각 옥텟은 부호없는 값으로 취급됩니다. 이 값은 부호없는 정수에 추가되고 0으로 초기화되며 정밀도는 17 비트 이상이어야합니다. 체크섬을 계산할 때 chksum
필드는 모두 <space> 문자 인 것처럼 처리됩니다 .물론 실제로 그렇게 할 필요 가 없습니다. tar
이미 할 수 있는 일이기 때문입니다. 따라서 아카이브를 검색하고 파일을 추출하는 데 사용해야합니다. 그렇게하면 자신이 무엇을하고 있는지 아는 경우와는 다른 방식으로 일을하지 않을 것입니다. 단, 그것이 직업이기 때문에 더 빠르고 더 잘할 것입니다. 어쨌든 왜해야합니까?