如何在嵌套 while 循环中从 bash 脚本中的标准输入读取多个输入文件

how to read multiple input files from stdin in bash script in nested while loop

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

example code

#!/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}" ;

i am reading file input from stdin using ./script.sh file1.txt but i wanted to input two files like

./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 .

首先,让我们创建一些数据文件。

cat <<EOF >file1.txt
AAA
EOF

cat <<EOF >file1.txt
BBB
EOF

现在创建一个批处理文件来读取它们。

cat <<-'EOF' > read-files.sh
#!/bin/bash

F1=
F2=

while IFS= read -r line 
do 
 LINE1=$line
done < $F1

while IFS= read -r line 
do
  LINE2=$line
done < $F2

echo $LINE1
echo $LINE2
EOF

使脚本可执行。

chmod +x read-files.sh

现在运行吧。

./read-files.sh file1.txt file2.txt
AAA
BBB

while循环内的变量line在循环外不可用。这就是为什么值被转移到 LINE1LINE2.

$ cat file1
a
b
c

.

$ cat file2
foo
bar

.

$ cat tst.sh
#!/usr/bin/env bash

while IFS= read -r outer; do
    echo "$outer"
    while IFS= read -r inner; do
        echo "    $inner"
    done < ""
done < ""

.

$ ./tst.sh file1 file2
a
    foo
    bar
b
    foo
    bar
c
    foo
    bar

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

#!/bin/bash

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

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

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