반복적으로 파일 압축

반복적으로 파일 압축

77K PDF(크기 약 500GB)가 포함된 폴더가 있습니다. 더 쉽게 업로드하고 동료와 공유할 수 있도록 각 파일에 1000개의 PDF가 포함된 77개의 압축 파일로 압축하고 싶습니다. Bash에서 for 루프를 작성하고 거기에서 zip 명령을 사용하는 방법을 모르지만 몇 가지 예를 보았습니다.이것질문. 누구든지 나를 도와줄 수 있나요?

파일 이름은 다음과 같습니다.

FinalRoll_MR_ACNo_@PartNo_%%.pdf

@ 및 %%는 숫자입니다. 처음 1000개의 파일을 archive_1.tar.gz와 같은 파일로 압축할 수 있다면 정말 좋을 것 같아요! 파일 순서를 알파벳순으로 유지할 수 있다면 더욱 좋을 것 같아요!

Ubuntu를 실행하는 AWS ec2 인스턴스를 사용하고 있습니다.

미리 감사드립니다!

답변1

#!/usr/bin/perl

use strict;
use List::MoreUtils qw(natatime);
use Sort::Naturally;

# specify directory on command line, or default to .
my $dir = shift || '.';

# Find all the PDF files. 
#
# NOTE: you could use perl's `Find::File` module instead of
# readdir() to do a recursive search like `find`.
opendir(DIR, $dir) || die "Can't open $dir: $!\n";
my @pdfs = nsort grep { /\.pdf$/i && -f "$dir/$_" } readdir(DIR);
closedir(DIR);

my $size=1000;

my $i=1;
my $iter = natatime $size, @pdfs;
while( my @tmp = $iter->() ){
  my $tarfile="archive_" . sprintf('%02i',$i++) . ".tar.gz";
  #print join(" ", ('tar','cfz',$tarfile, @tmp)),"\n";
  system('echo','tar','cfz',$tarfile, @tmp);
}

이는 natatime()Perl List::MoreUtils라이브러리 모듈의 ("n-at-a-time") 기능을 사용하여 한 번에 1000개의 PDF 파일 목록을 반복합니다.

또한 이 Sort::Naturally모듈을 사용하여 PDF 파일 이름의 자연스러운 순서를 수행합니다. 필요하지 않거나 원하지 않는 경우 해당 항목(및 통화 nsort중인 통화 )을 삭제하세요.my @pdfs = ...

올바른 정렬을 위해 tar 파일 이름에 0으로 채워진 숫자 2개를 포함합니다. 99개가 넘는 tar 아카이브를 채울 만큼 충분한 PDF 파일이 있는 경우 이를 3자리 이상으로 변경하세요.

작성된 코드는시운전. 실제로 PDF 파일 배치를 압축하도록 'echo',함수 호출에서 제거되었습니다 .system()

그것 없이 실행할 때 자세한 출력을 얻으려면 명령문 echo의 주석 처리를 제거하십시오 print. 그런데, Perl 내장 기능을 사용하거나 time()모듈을 사용하여 멋지게 형식을 지정하거나 신기원 이후 초 이후의 타임스탬프를 인쇄하는 것은 쉽습니다 Date::Format. 예를 들어:

print join(" ", (time(),'tar','cfz',$tarfile, @tmp)),"\n";

예를 들어, vibhu.pl실행 가능하게 만들려면 다른 이름으로 저장하세요 chmod +x vibhu.pl. 다음은 샘플 실행입니다(".pdf" 파일이 10개만 있는 디렉터리).

$ touch {1..10}.pdf
$ ./vibhu.pl 
tar cfz archive_01.tar.gz 1.pdf 2.pdf 3.pdf 4.pdf 5.pdf 6.pdf 7.pdf 8.pdf 9.pdf 10.pdf

$size=1000예를 들어 으로 변경하면 $size=3실제로 N개의 PDF 파일을 한 번에 수행하는 것을 볼 수 있습니다.

$ ./vibhu.pl 
tar cfz archive_01.tar.gz 1.pdf 2.pdf 3.pdf
tar cfz archive_02.tar.gz 4.pdf 5.pdf 6.pdf
tar cfz archive_03.tar.gz 7.pdf 8.pdf 9.pdf
tar cfz archive_04.tar.gz 10.pdf

이것목록::추가 유틸리티그리고정렬::자연모듈은 다음에서 제공됩니다.CPAN. 배포할 수 있도록 이미 패키지되어 있을 수도 있습니다. 예를 들어 Debian의 경우:

sudo apt-get install liblist-moreutils-perl libsort-naturally-perl

답변2

Bash 쉘을 사용하면 파일 이름을 배열에 넣은 다음(자연 순서를 위해 와일드카드 확장 사용) 인덱싱 루프에서 한 번에 1000개를 잘라낼 수 있습니다.

#!/bin/bash

filenames=( *.pdf )
for((index=1; index <= $(( (${#filenames[@]} / 1000) + 1)); index++))
do
  start=$(( (index-1) * 1000 ))
  tar czf archive"${index}".tar "${filenames[@]:start:999}"
done

for루프는 실행당 1000개의 파일을 가져오는 데 필요한 만큼 여러 번 실행됩니다. 이 start변수는 배열 슬라이스가 시작되어야 하는 위치를 나타냅니다. 이 tar명령은 배열의 1000개 파일에 대한 색인화된 tar 파일을 생성합니다. 파일 999부터 시작하여 start다음 999개 파일(또는 마지막 남은 파일)로 끝납니다.

답변3

이 awk 스크립트를 사용하여 쉘 스크립트를 만들 수 있습니다. 압축.sh를 확인하고 실행하세요.

ls *.pdf | awk 'BEGIN {ORS=""; print "#!/bin/sh"; } NR%1000 == 1 {  print "\nzip Archive_" NR ".zip"; } { print " \\\n" $0; }' > compress.sh

답변4

구문 분석하면 안 되므로 find 및 xargs를 사용하는 대안 ls:

export numfile="$(mktemp)"
echo 0 > "$numfile"

find lots_of_files/ -name '*.pdf' -print0 \
| sort -V -z \
| xargs -0r -L 1000  \
bash -c 'NUM=$(cat "$numfile") ; ((NUM++)); echo "$NUM" > "$numfile"; \
  tar -czf archive_$(printf '%03d' "$NUM" ).tar.gz "$@"' tar_in_batches

rm "$numfile"
unset numfile

앞에 0이 붙은 아카이브를 얻게 되며 아카이브의 파일은 올바른 순서가 됩니다.

파일 이름에 공백이나 줄 바꿈이 있어도 이 버전은 중단되지 않습니다.

관련 정보