首页 > 解决方案 > 如何在嵌套的while循环中从bash脚本中的stdin读取多个输入文件

问题描述

我想在“while do nested loop”中从标准输入读取两个文件,例如文件1第一行,然后处理所有文件2输入行,然后处理文件1第二行并处理文件2中的所有行,依此类推。

示例代码

#!/bin/bash
cd ~/files/ ;
while read line1;
do 
 echo "$line1"output;
while read line2;
do
echo $line1;
echo $line2;
echo "$line1"test"line2" | tee -a output.txt ;

done < "${1:-/dev/stdin}" ;

我正在使用 ./script.sh file1.txt 从标准输入读取文件输入,但我想输入两个文件,例如

./script.sh file1.txt file2.txt
i tried 
done < "${1:-/dev/stdin}" ;
done < "${2:-/dev/stdin}" ; 
its not working .
 also tried file descripters
like 
while read line1<&7;
while read line2<&8;
input like ./script.sh file1.txt 7< file2.txt 8
and it throws bad file descriptor error .

标签: bashwhile-loopterminalshstdin

解决方案


要访问内部循环中的两个文件,请在不同的文件描述符上打开它们。这是使用 FD #3 和 #4 的示例:

#!/bin/bash

while read line1 <&3; do    # Read from FD #3 ($1)
    while read line2 <&4; do    # Read from FD #4 ($2)
        echo "line1: $line1, line2: $line2"
    done 4<"${2:-/dev/stdin}"    # Read from $2 on FD #4
done 3<"${1:-/dev/stdin}"    # Read from $1 on FD #3

这是一个示例运行:

$ cat file1.txt 
one
two
$ cat file2.txt 
AAA
BBB
$ ./script.sh file1.txt file2.txt 
line1: one, line2: AAA
line1: one, line2: BBB
line1: two, line2: AAA
line1: two, line2: BBB

顺便说一句,其他一些建议:您应该(几乎)始终将变量引用放在双引号中(例如echo "$line1",而不是echo $line1)以避免奇怪的解析。行尾不需要分号(我在while ... ; do上面的语句中使用了分号,但这只是因为我把分号放在do同一行)。在脚本中使用时,您应该(几乎)始终检查错误cd(因此它不仅会一直在错误的位置运行,而且会产生不可预测的结果)。

shellcheck.net擅长指出常见的脚本错误;我推荐它!


推荐阅读