많은 수의 파일을 단일 디렉토리로 결합

많은 수의 파일을 단일 디렉토리로 결합

한 디렉토리에 현재 10,804개의 파일이 있습니다. 파일 수는 5~100,000개 사이일 수 있습니다.

저는 250개의 개별 파일을 하나의 큰 파일로 병합하고 나머지 파일을 하나의 작은 파일로 병합하는 방법을 찾고 있습니다. 예를 들어 1200개의 파일이 있으면 4,250개의 파일과 1,200개의 파일이 필요합니다.

나는 bash 쉘을 사용하고 있습니다.

답변1

배열을 사용하여 이 작업을 수행하는 간단한 루프를 작성할 수 있습니다.${x:s:l}매개변수 확장:

files=(*)
for (( i = 0; i < ${#files[@]}; i += 250 ))
do
    cat -- "${files[@]:$i:250}" > "file$i.combined"
done

.여기에서는 모든(숨겨지지 않은) 파일을 배열(어휘적으로 정렬된 파일 이름)로 수집 files하고 0부터 반복하여 250초 동안 파일 수를 계산합니다. 각 250에 대해 파일 이름(0-249, 250-499 등)을 인수로 확장하고 cat출력을 등에 넣습니다 file0.combined.file250.combined

이것은 전통적인 C 스타일 for루프의 Bash 버전입니다. 어쨌든 각각의 개별 루프에 대해 루프를 반복해야 하기 때문에 cat지나치게 복잡할 필요는 없습니다.

.combined여러 파일이 생성됩니다. 파일 이름이 확장되었으므로 이러한 파일은 다시 연결에 포함되지 않지만 명령을 두 번째로 실행하면 연결에 포함됩니다. 이것이 문제라면 다른 곳에 두고 삭제하거나 lp.

답변2

간단히:

#!/bin/bash
files_count=`ls -1 ./ | wc -l`
block_size=10
blocks_count=$(($files_count/$block_size))

for i in $(seq 1 1 $blocks_count); do
    files=`find . -type f -exec readlink -f {} \; | head -$block_size`
    for j in $files; do
        if [ -f $j ] && [[ "$j" != outfile* ]] ; then
            cat $j >> outfile$i
    fi
    done
done
# remainder part
for i in *; do
    if [ -f $i ] && [[ "$i" != outfile* ]] ; then
        cat $i >> outfilelast
    fi
done

노트:

파일은 알파벳 순서로 병합되며 스크립트는 동일한 디렉터리에 배치되어야 합니다.

답변3

나는 다음 방법을 사용해 보았습니다.

for ((i=1;i<=1200;i++)); do j=$(($i + 249 )); sed -n ''$i','$j'p' filename >individual_$i ;i=$j; done

답변4

find찾은 순서대로 결합 할 수 있다고 가정합니다 .

find . -maxdepth 1 -type f -print0 |
xargs -0 -L 250 sh -c 'cat "$@" >/tmp/combined-${1##*/}' sh

file-1예를 들어 최대 이름의 파일이 포함된 file-739디렉터리 의 경우 , 및 /tmp이라는 파일이 생성됩니다 . 여기서 다음 비트 는 결합된 파일의 첫 번째 파일 이름입니다.combined-file-1combined-file-251combined-file-501combined-

cat한 번에 최대 250개의 파일을 일괄적으로 연결하기 위해 반복적으로 실행되는 인라인 셸 스크립트를 호출하여 이 작업을 수행합니다 xargs( ${1##*/}이 스크립트는 현재 일괄 처리의 첫 번째 파일 경로 이름에서 모든 디렉터리 경로를 제거합니다). 유틸리티 xargs는 파일 이름을 null로 끝나는 문자열로 가져옵니다 find. 이 find유틸리티는 현재 디렉토리만 검색하여 일반 파일에 해당하는 모든 경로 이름을 출력합니다.

그런 다음 이 파일을 인쇄합니다 /tmp/combined-*.

예를 들어 특정 접미사가 있는 파일만 처리하려면 .txt명령 -name '*.txt'에서 findbefore를 사용합니다 -print0.

-print0일반적으로 수행되는 작업 및 find옵션은 비표준 -0입니다 .xargs

관련 정보