디렉터리에 있는 텍스트 파일 덩어리를 하나 이상의 파일로 병합한 다음 병합된 파일을 압축해야 합니다.
예: 디렉터리에 500,000개의 텍스트 파일이 있는 경우 A라고 말하세요. 50,000개의 파일 세트를 1개의 파일 세트로 병합하고 싶습니다. 즉, 각각 50,000개의 파일 내용을 포함하는 10개의 병합된 파일을 갖게 됩니다. 마지막으로 병합된 각 파일을 압축하고 싶습니다. 즉, 이 프로세스가 끝나면 총 10개의 zip 파일이 있게 됩니다.
쉘 스크립트에서 이 작업을 수행하려고 합니다. 해결책을 찾을 수 없습니다.
누군가 쉘 스크립트를 사용하여 이를 달성하는 가장 효율적인 방법을 알려주실 수 있습니까?
답변1
제가 보기에는 많은 수의 파일이 들어 있는 디렉토리가 하나뿐이므로 파일 목록을 연결하는 대신 작은 파일 세트로 분할한 다음 필요한 경우 작은 파일을 압축하고 삭제해야 합니다.
제가 제안할 수 있는 방법은 다음과 같습니다.
cd /to/dir/with/many/files/
mkdir ../tmp
find . | split -l 50000 ../tmp/x
for i in ../tmp/x* ; do
while read filename ; do
cat "$filename" >> "${i}.text" ;
# rm "$filename" # uncomment it only if you need to delete small files
done <"$i"
zip "${i}.zip" "${i}.text"
# rm "${i}.text" # uncomment it only if you need to delete result file
done
답변2
여기에는 두 가지 해결 방법이 있습니다. 하나는 n
파일을 단일 아카이브에 추가하는 것이고, 다른 하나는 먼저 모든 파일을 연결한 다음 압축하는 것입니다.
두 방법의 일반적인 단계는 다음과 같습니다.
# Generate a list of files to be zipped
find . -type f > filelist
# Loop to process n files stepwise
n=50000
fileno=1
for i in $(seq 1 $n $(wc -l < filelist)); do
# compression code goes here, see below
done
파일을 개별적으로 압축
# automatic name generation
zipfile=$(printf "%04d" $((fileno++)))
# extract lines $i to $i+$n-1 from filelist
sed -n "$i,$((i+n-1))p" filelist | zip $zipfile -@
연결 및 압축
(및 다른 압축기)를 사용하여 이 작업을 수행 하려면 gzip
매우 간단합니다.
zipfile=$(printf "%04d" $((fileno++)))
sed -n "$i,$((i+n-1))p" filelist | xargs cat | gzip > $zipfile.gz
이 모드는 지원되지 않으므로 zip
(적어도 내가 가지고 있는 모드는 아님) 다른 접근 방식이 필요합니다. zip
명명된 파이프( -FI
)가 지원됩니다. 여기서 아카이브 내부의 파일은 명명된 파이프의 이름을 가져오므로 루프 내에서 다음과 같은 작업을 수행하면 작동합니다.
zipfile=$(printf "%04d" $((fileno++)))
mkfifo $zipfile
zip -FI $zipfile $zipfile &
sed -n "$i,$((i+n-1))p" filelist | xargs cat > $zipfile
rm $zipfile