zip 아카이브에 여러 파일이 포함된 경우 디렉터리를 만듭니다.

zip 아카이브에 여러 파일이 포함된 경우 디렉터리를 만듭니다.

아카이브의 루트 디렉터리에 여러 파일이 포함된 경우 파일 이름을 딴 디렉터리(확장자 없음)를 만들고 싶습니다. 아카이브에 디렉토리가 하나만 포함되어 있으면 간단히 추출하고 싶습니다. 다음과 같은 아카이브가 있다고 가정해 보겠습니다.

# file: withdir.zip
somedir/alpha
somedir/beta
somedir/gamma

현재 디렉토리에 압축을 풀면 간단히 추출( unzip withdir.zip)하기를 원합니다.

somedir/alpha
somedir/beta
somedir/gamma

이제 다음 아카이브가 있다고 가정합니다.

# file: nodir.zip
alpha
beta
gamma

실행하면 unzip nodir.zip현재 디렉터리가 세 개의 파일로 복잡해집니다.

alpha
beta
gamma

차라리 다음을 실행하고 싶습니다 unzip -d nodir nodir.zip.

nodir/alpha
nodir/beta
nodir/gamma

노틸러스를 사용하고 "여기서 추출"을 마우스 오른쪽 버튼으로 클릭하면 됩니다. 예상대로 정확하게 작동합니다. 그러나 불행히도 동일한 동작을 생성하는 명령줄 스위치를 찾 unzip거나 생성 하지 못했습니다 . 7z이 목표를 달성하는 방법은 무엇입니까? GUI 없이 다른 도구를 사용할 수 있나요?

답변1

나는 다음과 같이 할 것입니다 (zsh 구문):

unz() (
  tmp=$(TMPDIR=. mktemp -d -- ${${argv[-1]:t:r}%.tar}.XXXXXX) || exit
  print -r >&2 "Extracting in $tmp"
  cd -- $tmp || exit
  [[ $argv[-1] = /* ]] || argv[-1]=../$argv[-1]
  (set -x; "$@"); ret=$?
  files=(*(ND[1,2]))
  case $#files in
    (0) print -r >&2 "No file created"
        rmdir -v "../$tmp";;
    (1) mv -v -- $files .. && rmdir -v ../$tmp;;
    (*) mv -vT ../$tmp ../$tmp:r;;
  esac && exit $ret
)

그건:

  1. 어쨌든 디렉토리를 생성하세요
  2. 명령 실행
  3. 명령으로 생성된 파일 수에 따라 다릅니다.
    • 디렉터리 삭제(파일이 생성되지 않은 경우)
    • 하나의 파일/디렉토리만 생성하는 경우 한 수준 위로 이동하고 디렉터리를 삭제합니다.
    • 그렇지 않은 경우 임시 디렉터리 끝에서 임의의 문자열을 제거해 보세요.

이 방법으로 다음을 수행할 수 있습니다.

unz unzip foo.zip
unz tar xf foo.tar.gz

extract 명령의 마지막 인수가 추출할 파일이라고 가정합니다. 또한 -v옵션이 GNU 도구를 사용한다고 가정합니다. GNU가 아닌 시스템에서는 이를 삭제하고 수동으로 기록할 수 있습니다. mv -T또한 GNU에만 해당되며 mv이름 바꾸기 시도만 강제합니다.

답변2

unzip둘 다 지정된 디렉터리로 출력하는 스위치가 있으므로 7z아카이브 루트에 파일 수를 확인하는 간단한 스크립트를 만든 다음 필요한 경우 스위치를 추가할 수 있습니다.

7z에는 스위치가 있어 -slt출력을 기계가 더 쉽게 읽을 수 있기 때문에 더 쉽습니다. 출력에는 zip의 각 파일에 대해 한 줄이 포함됩니다 Path = .... 루트 디렉터리의 파일에는 /값이 포함되어서는 안 됩니다.

나는 이런 방식으로 파일의 압축을 푸는 간단한 스크립트를 작성했습니다.

#!/bin/sh
for archive in "$@"; do
    # count files in root dir
    rootfiles=$(7z l -slt "${archive}" | grep -c 'Path = [^/]*$')

    # add -o switch, if more than one file in root
    # checks for >2, because path of the zip file itself is listed too
    if [ $rootfiles -gt 2 ]; then
        filename=${archive##*/}
        rootname=${filename%.*}
        opt="-o${rootname}"
    fi

    #unpack
    7z x "${opt}" "${archive}"
done

편집: 이제 스크립트는 zip에서도 작동합니다.

답변3

순찰대원다양한 유형의 아카이브를 처리하고 아카이브에 여러 파일이 포함된 경우 하위 디렉터리를 생성하여 추출된 파일이 작업 디렉터리를 복잡하게 만드는 것을 방지합니다.

프로필 만들기

patool create archive.zip somedirectory

아카이브 추출

patool extract archive.zip

지원되는 형식 목록을 얻으려면 patool formats.

답변4

당신은 또한 사용할 수 있습니다우날, 두 개 이상의 최상위 파일이 있는 경우 기본적으로 포함 디렉터리를 만듭니다.

$ touch 1 2
$ zip a.zip 1 2
  adding: 1 (stored 0%)
  adding: 2 (stored 0%)
$ unzip -l a.zip
Archive:  a.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  04-29-14 10:56   1
        0  04-29-14 10:56   2
 --------                   -------
        0                   2 files
$ unar a.zip
a.zip: Zip
  1  (0 B)... OK.
  2  (0 B)... OK.
Successfully extracted to "a".
$ ls a
1 2

-d항상 포함 디렉터리를 생성하도록 추가되었습니다 .

관련 정보