다른 디렉토리에 여러 파일을 압축하여 새 디렉토리에 복사


4

개별 .gz 파일로 압축 해야하는 다른 디렉토리에있는 여러 파일로 작업하고 있습니다. 또한 원본은 그대로두고 압축 파일을 단일 디렉토리로 이동해야합니다.

gzip 명령과 압축하려는 파일의 모든 파일 경로 목록이 포함 된 파일을 사용하여이를 수행하는 방법이 있습니까?

조금 오래 걸리면 사과합니다 ... 리눅스를 처음 접했을 때 더 효율적인 표현 방법을 생각할 수 없습니다.

답변:


4

파일 목록이 filelist 라는 파일 (정확히 한 줄에 하나의 파일 경로)에 저장되어 있고 압축 파일을 zipdir 에 저장하려는 경우이 bash 스크립트는 원하는 결과를 얻습니다.

#!/bin/bash

while IFS= read file; do
    gzip -c "$file" > "zipdir/$(basename "$file").gz"
done < filelist

bash / dash에서 위의 것을 하나의 라이너로 변환 할 수도 있습니다.

while IFS= read file; do gzip -c "$file" > "zipdir/$(basename "$file").gz"; done < filelist

다른 쉘 (예 : tcsh 또는 zsh)

bash -c 'while IFS= read file; do gzip -c "$file" > "zipdir/$(basename "$file").gz"; done < filelist'

일을 할 것입니다.

bash가 없으면 대시로 대체 할 수 있습니다.

작동 원리

  • ... < filelist의 내용을 리디렉션 파일 목록 에를 ....

  • while IFS= read file; do ... donefilelist의 행을 통과하고 현재 처리 된 행의 내용을 변수 파일에 저장 하고 실행 ...합니다.

    IFS=내부 파일 구분 기호를 수정합니다. 여러 개의 선행 및 후행 공백을 올바르게 처리하는 데 필요합니다.

  • gzip -c "$file" > "zipdir/$(basename "$file").gz"현재 처리 된 파일을 압축하고 zipdir 디렉토리의 확장자 가 .gz 인 파일에 출력을 저장합니다 .

    다음은 basename "$file"파일의 경로에서 베어 파일 이름을 추출합니다.


빠른 답변 감사합니다! 내가 가고 싶은 곳의 올바른 길에있는 것 같습니다. 그러나 내가 일하는 사람은 tcsh를 선호합니다 (그들이 배운 것 같아요) 그래서 내가 일하는 상자는 그 껍질에서 실행됩니다. 이것을 작성하여 tcsh에서 작동하는 방법이 있습니까?
David

위의 tcsh로 포팅하는 것은 너무 어렵지 않지만 그렇게하기에는 tcsh가 거의 충분하지 않습니다. bash가 설치되어 있으면 위의 내용을 스크립트에 저장하고 bash shebang을 추가하거나로 호출하면됩니다 bash -c.
Dennis

알았어 시도해 볼게요. 도와 주셔서 감사합니다 !!
David

그냥 이것을 시도하고 모든 것이 완벽하게 작동합니다! 그러나 한 가지 더 질문이 있습니다. flist의 끝에 도달하면 (다른 모든 파일을 성공적으로 복사 / 압축 한 후) 스크립트는 flist를 계속 읽으려고하지만 파일 경로가 남아 있지 않기 때문에 빈 .gz 파일 만 만들어줍니다. "이러한 파일이나 디렉토리가 없습니다."오류 스크립트가 끝에 도달했음을 알리기 위해 flist 끝에 추가 할 수있는 것이 있습니까?
David

스크립트는 공백에 민감합니다. 끝에 공백이 하나있는 줄이 있으면`.gz` 파일이 만들어집니다 (앞의 공백). 빈 줄 (공백 포함하지 않음)은 비슷한 오류가 발생하지만 빈 파일은 없습니다.
Dennis

0

gzip파일에서 경로를 읽는 것을 지원 하지 않는다고 생각 합니다. 해결 방법은 모든 대상 파일을 아카이브 (tar)에 넣거나 여러 번 실행하는 것입니다.

대상 디렉토리가 용량 또는 전송 속도와 관련하여 제한되지 않은 경우 가능한 해결책은 이 답변에 설명 된대로 대상 폴더에서 파일을 압축하기 전에 파일을 이동하는 입니다.

그렇지 않으면 한 번에 하나의 파일 이름을 읽고 폴더를 압축하고 생성 할 때 폴더를 만듭니다.

폴더 구조 생성

TARGET=~/tmp/out

while read line; do 
    dirname "$line" ; 
done < list.txt | sort -u |
xargs -I%  echo mkdir -p "$TARGET/%"

  ## out: ##
  mkdir /home/jaroslav/tmp/out/code/bash 
  mkdir /home/jaroslav/tmp/out/recipes
  mkdir /home/jaroslav/tmp/out/samba
  mkdir /home/jaroslav/tmp/out/wikipedia

파일 복사

while read line; do
   gzip -c "$SOURCE/$line" > "$TARGET/$line.gz"
done < list.txt

명령

  • dirname : 디렉토리를 남기고 파일 경로의 마지막 부분을 제거하십시오
  • read [arg] <file : 파일에서 한 번에 한 줄씩 읽고 쉘 변수 arg에 저장하십시오.
  • 종류 -u : 중복 된 항목 (휴가 제거 unique를)
  • xargs -I % : 파이프 (|)에서 모든 요소 (디렉토리 이름)마다 한 번씩 명령 (echo ....)을 실행합니다.
  • gzip -c in> out : 압축하여 stdout (-c)에 씁니다. > stdin을 명명 된 파일로 리디렉션합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.