un-zip, de-tar -xvf를 압축 해제하는 방법 — 지저분한 폴더에서 압축을 해제합니다.


14

보통, 나는 보관을 $ mkdir newFolder; $ mv *.zip newFolder; $ cd newFolder; $unzip *.zip하지 않지만 때로는 게으르고 임의의 폴더에서 작업 $ unzip *.zip하기 때문에 다른 콘텐츠와 시간을 망칠 수 있습니다. 여기에 몇 가지 방법이 있습니다. 일부 아카이브 버전에는 반드시 crappy-flags가 있지만 다른 아카이브는 스파르타가 많으며 후자는 더 관심이 있습니다.

보관을 해제하는 몇 가지 방법이 있습니까?

  1. $ find . -anewer fileThatExistedBeforeUnarchieving -ok rm '{}' \;약점은 *.zipdirs를 나열한다는 것입니다 . 따라서 -ok많은 *.zip일치 항목을 가지고 slow , slow 를 사용해야 하며 어떤 이유로 추출 된 모든 항목과 일치하지 않는 것 같습니다.

  2. 추출 된 파일이 적은 경우 하나씩, 느리고 번거롭고 오류가 발생하기 쉽습니다.

  3. 보관함의 내용이 실제로 폴더인지 확인하고 싶을 때 가끔 확인 $ unzip -l *.bsd하여 적어도 obsd의 unzip-version에서 작동합니다.

특정 보관 도구를 언급하는 경우 적절한시기에 보관하십시오. 그래도 간단하게 유지하십시오. 하나의 도구가 아니라 WAYS가 어떻게하는지 WAYS에 더 관심이 있습니다.



여기에 mkdir; unzip물건 을 자동화하는 데 사용하는 스크립트가 있으므로 너무 게으르지 않습니다! svn.mikelward.com/svn/scripts/untar
Mikel

2
이 관련 질문과 답변을 참조하십시오 : unix.stackexchange.com/questions/5123/…
alex

답변:


11

이름으로

압축 파일에서 파일 목록을 생성하고 삭제할 수는 있지만 unzip 또는 7z와 같은 평범한 파일 이름 목록을 생성 할 수있는 옵션이없는 아카이브에서는 성가신 일입니다. tar를 사용하더라도 파일 이름에 줄 바꿈이 없다고 가정합니다.

tar tf foo.tar | while read -r file; do rm -- "$file" done
unzip -l foo.zip | awk '
    p && /^ --/ {p=2}
    p==1 {print substr($0, 29)}
    /^ --/ {++p}
' | while …
unzip -l foo.zip | tail -n +4 | head -n -2 | while …  # GNU coreutils only
7z l -slt foo.zip | sed -n 's/^Path = //p' | while …  # works on tar.*, zip, 7z and more

파일을 제거하는 대신 원하는 대상으로 이동할 수 있습니다.

tar tf foo.tar | while read -r file; do
  if [ -d "$file" ]; then continue; fi
  mkdir -p "/intended/destination/${file%/*}"
  mv -- "$file" "/intended/destination/$file"
done

퓨즈 사용

외부 도구에 의존하는 대신, 대부분의 유니스에서 FUSE 를 사용하여 일반 파일 시스템 명령을 사용하여 아카이브를 조작 할 수 있습니다.

Fuse-zip 을 사용하여 Zip 을 들여다보고,로 추출하고 cp, 내용을 find등으로 나열 할 수 있습니다 .

mkdir /tmp/foo.d
fuse-zip foo.zip /tmp/foo.d
## Remove the files that were extracted mistakenly (GNU/BSD find)
(cd /tmp/foo.d && find . \! -type d -print0) | xargs -0 rm
## Remove the files that were extracted mistakenly (zsh)
rm /tmp/foo.d/**(:"s~/tmp/foo.d/~~"^/)
## Extract the contents where you really want them
cp -Rp /tmp/foo.d /intended/destination
fusermount -u foo.d
rmdir foo.d

AVFS 는 모든 아카이브에 아카이브 컨텐츠를 보유하는 것으로 보이는 연관된 디렉토리 (끝에 #가 붙은 동일한 이름)가있는 전체 디렉토리 계층의보기를 작성합니다.

mountavfs
## Remove the files that were extracted mistakenly (GNU/BSD find)
(cd ~/.avfs/"$PWD/foo.zip#" && find . \! -type d -print0) | xargs -0 rm
## Remove the files that were extracted mistakenly (zsh)
rm ~/.avfs/$PWD/foo.zip\#/**/*(:"s~$HOME/.avfs/$PWD/foo.zip#~~"^/)
## Extract the contents where you really want them
cp -Rp ~/.avfs/"$PWD/foo.zip#" /intended/destination
umountavfs

날짜 별

추출과 동일한 계층 구조에 다른 활동이 없다고 가정하면 추출 된 파일을 최근 ctime으로 알 수 있습니다 . zip 파일을 방금 생성하거나 이동 한 경우 컷오프로 사용할 수 있습니다. 그렇지 않으면 ls -lctr적절한 차단 시간을 결정하는 데 사용하십시오 . 지퍼를 제거하지 않으려면 수동 승인을 수행 할 이유가 없습니다. find완전히 제외 할 수 있습니다. 다음은 zsh 또는 find;를 사용하는 명령 예입니다 . 주의 -cmin-cnewer예비 선거는 POSIX에 아니지만 리눅스 (와 GNU의 발견과 다른 시스템)에 존재, * BSD와 OSX.

find . \! -name '*.zip' -type f -cmin -5 -exec rm {} +  # extracted <5 min ago
rm **/*~*.zip(.cm-6)  # zsh, extracted ≤5 min ago
find . -type f -cnewer foo.zip -exec rm {} +  # created or moved after foo.zip

GNU find, FreeBSD 및 OSX에서 컷오프 시간을 지정하는 다른 방법은 파일을 작성 touch하고 mtime을 컷오프 시간으로 설정 하는 데 사용 하는 것입니다.

touch -d … cutoff
find . -type f -newercm cutoff -delete

파일을 제거하는 대신 원하는 대상으로 이동할 수 있습니다. 다음은 GNU / * BSD / OSX find를 사용하여 필요에 따라 대상에 디렉토리를 작성하는 방법입니다.

find . \! -name . -cmin -5 -type f -exec sh -c '
    for x; do
      mkdir -p "$0/${x%/*}"
      mv "$x" "$0/$x"
    done
  ' /intended/destination {} +

Zsh와 동등 (거의 : 파일을 포함 할 디렉토리 만이 아니라 전체 디렉토리 계층을 재생 성함) :

autoload zmv
mkdir -p ./**/*(/cm-3:s"|.|/intended/destination|")
zmv -Q '(**/)(*)(.cm-3)' /intended/destination/'$1$2'

경고, 나는이 답변에서 대부분의 명령을 테스트하지 않았습니다. 제거하기 전에 항상 파일 목록을 검토하십시오 ( echo먼저 실행 한 다음 rm정상인 경우).


나는 오늘이 문제에 부딪쳤다. 루트로! 결국 나는 "이름으로"와 "날짜로"의 조합을 사용했다
phunehehe

1

어쨌든 나는 비슷한 문제가있을 때이 스크립트를 작성하기 위해 머리를 긁었습니다. 내가 사용 cpio-it파일의 목록을 얻을 플래그; 다른 아카이버에 동등한 명령을 사용할 수 있습니다. 까다로운 부분은 cpio 아카이브가 initrd에서 추출되어로 추출되어 /많은 폴더와 파일이 작업 시스템과 동일한 이름을 갖습니다. 운 좋게도 cpio는 기존 파일을 덮어 쓰지 않았습니다. 시간 검사를 사용하여 잘못된 명령 앞에 있던 것을 삭제하지 않도록합니다.

#! /bin/sh

files=$(cpio -it < /mnt/temp/lglive.cpio)

for i in ${files}
do
    name=$(stat -c "%n" ${i})
    time=$(stat -c "%Y" ${i})
    # Time of the creation of the mess: 1296457595
    if [[ ${time} -gt 1296457590 && ${time} -lt 1296457600 ]]
    then
        if [[ -f ${name} ]]
        # If it is a file, it must have been created as part of the mess.
        then
            echo "rm ${name}"
        elif [[ -d ${name} ]]
        # If it is a directory, it may have been part of the mess
        # or maybe some files underneath it is created as part of the mess.
        then
            if [[ $(ls -A ${name}) ]]
            # If the directory contains something then don't delete it.
            then
                echo "${name} is not empty"
            # If the directory is empty then assume it is rubbish.
            else
                echo "rmdir ${name}"
            fi
        fi
    fi
done

echo "Files and directories still exist after the removal:"
for i in ${files}
do
    if [[ -e ${i} ]]
    then
        echo ${i}
    fi
done

0

아카이브의 파일 목록을에 공급하는 것은 xargs rm어떻습니까?

즉 것 tar -tf tarbomb.tar | xargs rmunzip --list zipbomb.zip | xargs rm.


2
주어진 명령은 일반적으로 작동하지 않으며 파일을 제거하기 때문에 위험 합니다. 생산되지 않은 xargs독특한 방식으로 입력을 인용 find합니다. xargs -I rm {}xargs가 대신 라인 당 하나의 항목을 처리하도록 사용하십시오 . unzip 명령의 경우 어떤 구현이 있습니까? 광산 (데비안 / 우분투)가 없습니다 --list-l, 그것은 단지 추가 처리가 필요 그래서, 파일 이름을 인쇄하지 않습니다.
Gilles 'SO- 악의를 멈춰라'

@Gilles : 1) 예, 위험합니다. 그러나 원래 파일을 덮어 쓴 것으로 추정되므로 이미 사라졌습니다. 2) 나는 이야기하지 않았다 find. 3) 당신은 unzip, 나는 테스트하지 않았으며 장식되지 않은 리스팅에 대한 옵션이없는 것 같습니다. 아니 --list내 우분투뿐만 아니라 - 난 그냥 테스트하지 않았다.
alex

미리 준비된 답변에 대해 죄송합니다 . 대신 tar -t사용 find하세요. 그러나 내 다른 요점이 서 있습니다. 주어진 명령에 따라 관련되지 않은 파일이 삭제 될 위험이 있습니다.
Gilles 'SO- 악의를 멈춰라'

tar -tf tarbomb.tar파일 이름을 한 줄에 하나씩 인쇄하므로 tar -tf tarbomb.tar | while IFS=$'\n' read -r filename; do rm "$filename"; done비슷한 작업을 수행 할 수 있습니다.
Mikel

0

실제로 요청한 것이 아니라 "전체 압축 해제"스크립트를 대신 사용하는 방법에 대해 설명합니다.

unzip *.zip

그렇게하면 각 파일의 출력이 자체 디렉토리로 이동합니다.

#!/bin/bash
for f in *.zip ; do unzip -n "$f" -d "${f/%zip/out}"; done

0

zsh에서 다음 기능을 사용합니다.

ununzip () {
    rm -r $(unzip -l $1 | grep -v 'Archive:' | \
    grep '[/.]' | sed 's![^a-zA-Z]([a-zA-Z./])!\1!')
}

즉, 정리 된 출력의 모든 파일을 제거하는 명령 대체입니다 unzip -l.

tar tvf 비슷한 방식으로 사용될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.