ngram-merge
我想使用 SRILM 的程序合并一堆语言模型 (LM) 计数文件。通过该程序,我可以合并计数文件的整个目录,例如ngram-merge -write combined_file -- folder/*
.然而,根据我的数据量,它会运行几天,所以我很想并行合并文件!
下面的脚本基本上执行以下操作:
- 它将目录中的文件分成两个大小相等的集合(如果文件数量是奇数,则在构建集合之前合并两个文件)
- 它循环遍历集合并将两个文件合并在一起,从而将新文件写入新的子目录(这应该并行完成)
- 检查新子目录中是否只有一个文件;如果没有,1.在新创建的子目录中重新启动
不幸的是,该脚本可以工作,但ngram-merge
命令不是并行编译的。你能解决这个问题吗?此外,动态创建的文件夹结构有点难看。而且我也不是 shell 专家。所以我会感谢每一个让整个事情变得更加优雅的评论!谢谢 :-)
#!/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