파일이 1개만 남을 때까지 파일을 쌍으로 병렬로 병합합니다.

파일이 1개만 남을 때까지 파일을 쌍으로 병렬로 병합합니다.

ngram-mergeSRILM의 프로그램을 사용하여 여러 언어 모델(LM) 카운트 파일을 병합하고 싶습니다. 이 프로그램을 사용하면 계산된 파일의 전체 디렉터리를 병합할 수 있습니다 ngram-merge -write combined_file -- folder/*. 그러나 내가 가지고 있는 데이터의 양에 따라 며칠 동안 실행되므로 파일을 병렬로 병합하고 싶습니다!

아래 스크립트는 기본적으로 다음을 수행합니다.

  1. 디렉터리의 파일을 동일한 크기의 두 세트로 분할합니다. (파일 수가 홀수인 경우 세트를 구성하기 전에 두 파일을 병합합니다.)
  2. 컬렉션을 반복하고 두 파일을 병합하여 새 파일을 새 하위 디렉터리에 씁니다(이 작업은 병렬로 수행되어야 함).
  3. 새 하위 디렉터리에 파일이 하나만 있는지 확인하고, 그렇지 않은 경우 1. 새로 생성된 하위 디렉터리에서 다시 시작합니다.

불행하게도 스크립트는 작동하지만 ngram-merge명령은 병렬로 컴파일되지 않습니다. 이 문제를 고칠 수 있나요? 그리고 동적으로 생성된 폴더 구조도 좀 보기 흉합니다. 그리고 저는 쉘 전문가가 아닙니다. 따라서 모든 것을 더욱 우아하게 만드는 모든 의견에 감사하겠습니다! 감사해요:-)

#!/bin/bash

# Get arguments
indir=$1
# Count number of files
number="$(ls -1 $indir | wc -l)"
# Determine number of cores to be used in parallel
N=40

# While more than one file, combine files
while [ "$number" -gt 1 ]; do

    # determine splitpoint
    split="$((number/2))"
    # Determine whether number of files is odd
    if [ $((number%2)) -eq 1 ]
        # if it is odd, combine first and last file and rm last file
        then
            first="$indir$(ls -1 $indir | head -1)"
            last="$indir$(ls -1 $indir | tail -1)"
            new="$first""$last"
            /vol/customopt/lamachine.stable/bin/ngram-merge -write $new -- $first $last && rm -r $first $last
    fi

    # Determine first half of files and second half
    set1="$(ls -1 $indir | head -$split)"
    set2="$(ls -1 $indir | head -$((split*2)) | tail -$split)"
    # Make new dir
    newdir="$indir"merge/
    mkdir $newdir

    # Paralelly combine files pairwise and save output to new dir
    (
    for i in $(seq 1 $split); do
        file1="$indir$(echo $set1 | cut -d " " -f $i)"
        file2="$indir$(echo $set2 | cut -d " " -f $i)"
        newfile="$newdir""$i".counts
        /vol/customopt/lamachine.stable/bin/ngram-merge -write $newfile -- $file1 $file2 && rm -r $file $file2
        ((i=i%N)); ((i++==0)) && wait
    done
    )

    # Set indir = newdir and recalculate number of files
    indir=$newdir
    number="$(ls -1 $indir | wc -l)"

done

답변1

모르므 ngram-merge로 다음을 사용합니다 cat.

n=$(ls | wc -l)
while [ $n -gt 1 ]; do
  parallel -N2 '[ -z "{2}" ] || (cat {1} {2} > '$n'.{#} && rm -r {} )' ::: *;
  n=$(ls | wc -l);
done

그러나 다음과 같이 보일 수 있습니다.

n=$(ls | wc -l)
while [ $n -gt 1 ]; do
  parallel -N2 '[ -z "{2}" ] || ( /vol/customopt/lamachine.stable/bin/ngram-merge -write '$n'.{#} -- {1} {2} && rm -r {} )' ::: *;
  n=$(ls | wc -l)
done

관련 정보