在管道输出中添加间歇性ID

时间:2013-02-15 19:54:33

标签: bash scripting

我想迭代一个文档文件列表,处理它们并将结果输出到一个文件中,但是指示了文件ID。 处理涉及:标记删除,标记化,句子分割。

输入是这样的:

/path/to/file1 docid1 
/path/to/file2 docid2

输出将是令牌,每行一个,标记包含docid和句子nr:

<D=docid1.1>
tok1
tok2
</D>
<D=docid1.2>
...
</D>
<D=docid2.1>
...
</D>

我现在的做法如下:

>$outfile
for filename_id in `cat $filelist`
do
 filename=`echo $path_id | cut -f1 -d' '`
 docid=`echo $path_id | cut -f2 -d' '`

 strip_markup.sh $filename \
 | tokenize.sh \
 | sentence_split.sh \
 | add_ids.sh $docid
 | >> $outfile
done

现在的问题是我有相当多的小文件,并且每个步骤都有一些启动时间(启动JVM,加载模型等),其中一些非常重要。实际运行时间非常快,如非常大(人工)文件所示。 通过分析得出这个步骤(标记化和句子分割)是我项目中最耗时的步骤(其他一些概念上更“复杂”的东西运行得更快。)

基本上我想要做的是给strip_markup.sh脚本提供整个文件列表而不是单个文件名,但是之后需要以某种方式插入id。如果不是绝对必要,则不应更改输入和输出格式。 我们也想使用我们用于标记化和分割的模块,因为很多数据已经以这种方式处理。

任何想法如何去做?

1 个答案:

答案 0 :(得分:1)

我可以假设add_ids.sh只是添加<D=$docid>行并在其输入后添加</D>行吗?也许以下内容可行。注意我使用while循环和read命令来提取文件名和docid而无需外部进程。

< $filelist
while read filename docid; do
    echo "<D=$docid>"
    strip_markup.sh $filename |
    tokenize.sh |
    sentence_split.sh
    echo "</D>" 
done > $outfile

由于循环体中的所有标准输出都被一次序列化到输出文件,因此不需要单独的进程将标记化和拆分数据作为输入,以便将其包装在<D元素中。总而言之,这种方法每次迭代都会删除几个进程(两个子shell和用于处理输入的关联cut以及add_ids.sh的进程)。