디렉터리의 텍스트 파일 블록을 하나 이상의 파일로 병합하는 방법은 무엇입니까?

디렉터리의 텍스트 파일 블록을 하나 이상의 파일로 병합하는 방법은 무엇입니까?

디렉터리에 있는 텍스트 파일 덩어리를 하나 이상의 파일로 병합한 다음 병합된 파일을 압축해야 합니다.

예: 디렉터리에 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

관련 정보