zip 파일을“확실 해제”하는 방법은 무엇입니까? 비어 있지 않은

비어 있지 않은 폴더에 zip 파일을 추출했습니다. zip 파일에는 대상 디렉토리의 기존 트리와 병합 된 많은 파일과 깊은 계층 구조가 있습니다. 이미 존재하는 파일과 디렉토리를 손상시키지 않고 압축을 풀어 생성 한 파일과 디렉토리를 어떻게 제거 할 수 있습니까? 물론, 여전히 병합 한 zip 파일이 있으므로 정보가 있습니다.



답변

jjlin 의 답변은 갈 길입니다. 디렉토리에 대한 몇 가지 선택 사항을 추가하고 싶습니다.

  • 디렉토리가없는 추출 된 파일을 모두 삭제하십시오 .

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm "$n"; done
  • 추출 된 파일 및 디렉토리 만 삭제

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm "$n"; done; rmdir *

    옵션이 없으면 rmdir빈 디렉토리 만 삭제하고 파일과 비어 있지 않은 폴더 만 남겨두고 안전하게 실행할 수 있습니다 *.

  • 추출 된 모든 항목을 삭제 하지만 각 삭제 전에 확인 메시지를 표시하십시오.

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm -ri "$n"; done; rmdir *

    -i플래그가 발생할 rm때마다 제거하기 전에 확인하도록, 당신은 예 또는 아니오를 선택할 수 있습니다

  • 추출 된 모든 디렉토리를 삭제하십시오 .

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm -rf "$n"; done

답변

unzip -lqq <filename.zip>zip 파일의 내용을 나열하는 데 사용할 수 있습니다 . 여기에는 필터링해야 할 외부 정보가 포함됩니다. 나를 위해 작동하는 명령은 다음과 같습니다.

unzip -lqq file.zip | awk '{print $4;}' | xargs rm -rf

awk명령은 파일과 디렉토리의 이름 만 추출합니다. 그런 다음 결과가 xargs모든 항목을 삭제하도록 전달됩니다 . xargs rm -rf결과가 올바른지 확인하기 위해 명령을 드라 이런 (즉, 부품 생략)하는 것이 좋습니다 .

위 명령에는 공백이있는 경로를 처리하는 데 문제가 있습니다. 이 (더 복잡한) 버전은 다음을 수정해야합니다.

unzip -lqq file.zip | awk '{$1=$2=$3=""; sub(/ */, "", $0); printf "%s%s", $0, "\0"}' | xargs -0 rm -rf


답변

switch를 사용하면 -Z1unzip은 한 줄에 정확히 하나의 파일을 나열합니다 (다른 것은 없습니다).

이런 식으로, 당신은 사용할 수 있습니다

unzip -Z1 | xargs -I {} rm '{}'

zip 파일에서 추출 된 모든 파일을 삭제합니다.

명령

unzip -Z1 | xargs -I {} rm -rf '{}'

디렉토리도 삭제되지만주의해야합니다. zip 파일을 추출하기 전에 디렉토리가 이미 존재하면 해당 디렉토리에있는 모든 기존 파일도 삭제됩니다.


어쨌든 zip 파일을 다시 추출하려면 이상한 파일 이름을 처리하는 다른 방법이 있습니다.

먼저 원래 압축을 푼 zip 파일을 추출하십시오.

unzip file.zip -d elsewhere

이제 실수로 파일을 추출한 디렉토리로 변경하고 다음 명령을 실행하십시오.

find elsewhere -type f -printf "%P\0" | xargs -0 -I {} rm '{}'
  • -type f 파일 만 찾습니다 (디렉토리 없음).

  • %P\0상대 경로 (제외 elsewhere/)와 그 뒤에 null 문자

  • -0xargs를 널 문자로 구분하여 행을 만듭니다. 이론적으로 파일 이름에는 개행 문자가 포함될 수 있으므로이 방법이 더 안정적입니다.


남은 디렉토리를 처리하기 위해 다음 명령을 실행할 수 있습니다.

find -type d -exec rmdir -p {} \; 2> /dev/null
  • -type d 디렉토리 만 찾습니다.

  • -exec rmdir -p {} \;rmdir -p {}발견 된 모든 디렉토리에 대해 실행 됩니다.

    {}발견 된 디렉토리이며, -p스위치는 rmdir이 빈 상위 디렉토리도 제거하도록합니다.

  • 2> /dev/null 비어 있지 않거나 이전에 삭제 된 디렉토리를 삭제하려고 할 때 발생하는 오류 메시지를 표시하지 않습니다.


관련 매뉴얼 페이지 :


답변

더 쉽고 안전한 솔루션이라고 생각합니다.

zip -m getmeoutofhere.zip `unzip -lqq myoriginalzipfile.zip`
rm getmeoutofhere.zip

수행중인 작업 : 역 따옴표로 묶인 unzip 명령은 원본 파일의 내용 목록을 생성합니다.

그런 다음 zip -m은 해당 목록을 사용하여 각 항목을 getmeoutofhere.zip에 추가 하고 원래 디렉토리에서 제거합니다. 이론적으로 myoriginalfile.zip에 필수적입니다.

단점은 unzip -lqq 가 추가 텍스트, 날짜, 시간, 파일 크기 등을 생성한다는 것입니다. 이러한 경우 zip -m은 오류 메시지를 생성하지만 아무런 영향을 미치지 않습니다 (같은 파일을 가진 경우가 아니라면) 이름).

이렇게하면 원래 압축 해제 중에 작성된 디렉토리는 제거되지 않습니다.


답변

아카이브의 수정 타임 스탬프가 추출 된 사본에 보존되지 않도록 파일을 추출한 경우 (추출 된 파일의 일반적인 수정 시간이 있음)이를 공격하는 올바른 방법은 수정 시간을 통하는 것입니다. 추출 된 모든 파일에는 해당 디렉토리에서 가장 최근에 수정 된 기존 파일보다 새로운 수정 시간 소인이 있습니다.

간단한 상황이 있습니다.

현재 디렉토리의 기존 파일 중 적어도 24 시간 동안 아무것도 터치하지 않았다고 가정하십시오. 지난 24 시간 동안 수정 된 것은 zip 파일에서 정크입니다.

$ find . -mtime -1 -print0 | xargs -0 rm

이것도 일부 디렉토리를 찾을 수 있지만, rm그대로 두게됩니다. 그들은 두 번째 패스에서 처리 할 수 ​​있습니다.

$ find . -mtime 1 -type d -print 0 | xargs -0 rmdir

최근에 수정 된 디렉토리는 zip으로 수정되었습니다. rmdir성공적으로 제거 되면 비어있는 것입니다. zip에 의해 터치 된 빈 디렉토리는 아마도 그 디렉토리에 의해 생성되었을 것입니다. 100 % 확신 할 수는 없습니다. 압축 해제 작업이 일부 파일을 비어있는 기존 디렉토리에 넣을 수 있습니다.

경우 find트리에서 파일이 너무 최근에 수정 되었기 때문에 ‘의 24 시간 단위는 일을 위해 충분하지 않습니다, 나는 다음 간단한 무언가를 생각 하는데요 : 압축 해제 작업이 기존의 하위 디렉토리에 아무것도 넣지 않았다고 가정합니다. 즉, 압축이 풀린 모든 파일은 최상위 레벨의 파일이거나 이전에 없었던 새로운 하위 디렉토리이므로 Zip의 자료 만 포함합니다. 그때:

# list directory in descending order of modification time
$ ls -1t > filelist  # descending order of modification time

이제 filelist텍스트 편집기에서 열고 zip에서 나오지 않은 목록의 첫 번째 항목을 결정합니다. 해당 항목과 그 이후의 모든 항목을 삭제합니다. 남아있는 것은 우편 번호에서 온 파일과 디렉토리입니다. 먼저 이름의 공백과 이스케이프해야 할 따옴표 발생과 같은 문제를 육안으로 검사합니다. 그런 다음 필요한 경우 모든 것을 따옴표로 묶을 수 있습니다. 다음은 Vim을 사용한다고 가정합니다.

:%s/.*/"&"/

그런 다음 큰 줄로 묶으십시오.

:%j

이제 그 rm -rf앞에 삽입 하십시오 :

Irm - rf<ESC>

커서 아래에서 행을 쉘 명령으로 실행하십시오.

!!sh<Enter>

확실히, 나는 이미 존재하는 파일을 지우거나 파일 이름 문제로 인해 망할 위험으로 인해이 작업 단계를 자동화하지 않습니다.

zip의 경로 목록을 얻는 명확한 경로를 찾으려면 파일로 캡처하고 매우 신중하게 살펴보고 필요한 편집을 수행 한 후 제거로 변환하십시오.


답변