在bash中读取多个文件

时间:2015-04-02 20:34:21

标签: bash sed

我有两个.txt文件,我想在.sh脚本中同时读取每行的行数。两个.txt文件都有相同的行数。在循环内部我想使用sed-command来更改另一个文件中的full_sample_name和sample_name。 我知道如果你只是阅读一个文件,它是如何工作的,但我不能让它适用于两个文件。

#! /bin/bash

FULL_SAMPLE="file1.txt"
SAMPLE="file2.txt"

while read ... && ...
do
    sed -e "s/\<full_sample_name\>/$FULL_SAMPLE/g" -e "s/\<sample_name\>/$SAMPLE/g" pipeline.sh > $SAMPLE.sh

done < ...?

3 个答案:

答案 0 :(得分:5)

#!/bin/bash

full_sample_file="file1.txt"
sample_file="file2.txt"

while read -r -u 3 full_sample_name && read -r -u 4 sample_name; do
    sed -e "s/\<full_sample_name\>/$full_sample_name/g" \
        -e "s/\<sample_name\>/$sample_name/g" \
        pipeline.sh >"$sample_name.sh"
done 3<"$full_sample_file" 4<"$sample_file" # automatically closed on loop exit

在这种情况下,我将文件描述符3分配给file1.txt,将文件描述符4分配给file2.txt。


顺便说一句,使用bash 4.1或更新版本,您不再需要手动处理文件描述符:

# opening explicitly, since even if opened on the loop, these need
# to be explicitly closed.
exec {full_sample_fd}<file1.txt
exec {sample_fd}<file2.txt

while read -r -u "$full_sample_fd" full_sample_name \
   && read -r -u "$sample_fd" sample_name; do
  : do stuff here with "$full_sample_name" and "$sample_name"
done

# close the files explicitly
exec {full_sample_fd}>&- {sample_fd}>&-

还有一点需要注意:如果您的sample_namefull_sample_name值在被解释为正则表达式时无法自我评估,那么您可以提高效率(也更正确) ,如果您的输入文件不包含任何文字NUL [作为shell脚本,它不应该&#39; t],如果箭头括号是文字而不是字边界正则表达字符,则不使用{{1}根本没有,只是读取要转换为shell变量的输入,并在那里进行替换!

sed

答案 1 :(得分:5)

查尔斯提供了一个非常好的答案。

您可以使用paste加入文件行,并使用某些分隔符(不应出现在文件中):

paste -d ":" file1.txt file2.txt | while IFS=":" read -r full samp; do
    do_stuff_with "$full" and "$samp"
done

答案 2 :(得分:2)

使用GNU Parallel,它将如下所示:

#! /bin/bash

do_sed() {
    sed -e "s/\<full_sample_name\>/$1/g" -e "s/\<sample_name\>/$2/g" pipeline.sh > "$2".sh
}
export -f do_sed   

parallel --xapply do_sed {1} {2} :::: file1.txt file2.txt

额外的好处是你可以并行运行它。根据您的存储系统,这可能会加快处理速度:在raid6上我通过并行运行10个作业看到了6倍的加速。 YMMV,所以唯一可以确定的方法是测试和测量。

GNU Parallel是一个通用的并行程序,可以很容易地在同一台机器上或在你有ssh访问权限的多台机器上并行运行作业。

如果要在4个CPU上运行32个不同的作业,并行化的直接方法是在每个CPU上运行8个作业:

Simple scheduling

GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:

GNU Parallel scheduling

<强>安装

如果没有为您的发行版打包GNU Parallel,您可以进行个人安装,不需要root访问权限。这可以在10秒内完成:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README

了解详情

查看更多示例:http://www.gnu.org/software/parallel/man.html

观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel