在bash中读取多个文件

use*_*607 2 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 < ...?
Run Code Online (Sandbox Code Playgroud)

Cha*_*ffy 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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我将文件描述符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}>&-
Run Code Online (Sandbox Code Playgroud)

还有一点需要注意:如果您的输入文件不包含任何文字NUL [作为shell ,那么如果您的sample_namefull_sample_name值在被解释为正则表达式时无法保证自己评估,那么您可以使这更有效(并且更正确)脚本,它不应该],如果箭头括号是文字而不是字边界的正则表达式字符)完全不使用sed,只是读取输入要转换为shell变量,并在那里进行替换!

exec {full_sample_fd}<file1.txt
exec {sample_fd}<file2.txt
IFS= read -r -d '' input_file <pipeline.sh

while read -r -u "$full_sample_fd" full_sample_name \
   && read -r -u "$sample_fd" sample_name; do
  output=${input_file//'<full_sample_name>'/${full_sample_name}}
  output=${output//'<sample_name>'/${sample_name}}
  printf '%s' "$output" >"${sample_name}.sh"
done

# close the files explicitly
exec {full_sample_fd}>&- {sample_fd}>&-
Run Code Online (Sandbox Code Playgroud)


gle*_*man 5

查尔斯提供了一个很好的答案.

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

paste -d ":" file1.txt file2.txt | while IFS=":" read -r full samp; do
    do_stuff_with "$full" and "$samp"
done
Run Code Online (Sandbox Code Playgroud)