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



我想在"而执行嵌套循环";像文件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}" ;

我正在使用从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 .

要访问内部循环中的两个文件,请在不同的文件描述符上打开它们。下面是一个使用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擅长指出常见的脚本错误;我推荐它!

$ 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 < "$2"
done < "$1"

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

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

cat <<EOF >file1.txt
AAA
EOF
cat <<EOF >file1.txt
BBB
EOF

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

cat <<-'EOF' > read-files.sh
#!/bin/bash
F1=$1
F2=$2
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

最新更新