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


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.