Bash shell脚本中带有IFS的嵌套while循环

4

我正在尝试使用Bash Shell脚本解析一组CSV文件,文件如下所示:

File1: /tmp/test.txt
key1,key1file.txt
key2,key2file.txt
key3,key3file.txt

Files: /tmp/inter/key1file.txt
abc,cdf,123,456

Files: /tmp/inter/key2file.txt
abc,cdf,123,456

Files: /tmp/inter/key3file.txt
abc,cdf,123,456

我曾试过使用2个while循环解析这些文件:
while IFS="," read keycol keyfile
do
    while IFS="," read keyval
     do
     echo "inside inner while loop"
     echo "$keycol|$keyval"
    done < "/tmp/inter/$keyfile"
done < /tmp/test.txt

期望这段代码输出什么。
key1,abc
key1,cdf
key1,123
key1,456 and so on...

然而,当我运行这段代码时没有任何输出,这表明第二个循环没有被执行。任何指向正确方向的提示都会有所帮助。谢谢。

你在一个地方有/tmp/test.txt,在另一个地方有/tmp/test.csv。就是这样吗? - John Kugelman
在外部循环中添加一个打印输出。那个循环是否正在运行? - John Kugelman
通常情况下,read 函数无法解析 CSV 文件;它不能处理那些被转义为字段一部分而不是分隔两个字段的逗号。使用一种具有适当的 CSV 解析器的编程语言。 - chepner
1个回答

4
在您的第二个循环中,您没有正确地按,进行分割。read通常通过IFS进行分割,并将值分配给变量,每个变量一个字段,剩余的则放在提供的最后一个变量中。但如果您只提供一个变量,那么所有内容都会存储在其中。
相反,让read,进行分割为一个数组,然后循环遍历该数组中的值,就像这样:
#!/bin/bash
while IFS="," read keycol keyfile; do
    while IFS="," read -a values; do
        for val in "${values[@]}"; do
            echo "$keycol,$val"
        done
    done < "/tmp/inter/$keyfile"
done < /tmp/test.txt

您将得到以下内容:

key1,abc
key1,cdf
key1,123
key1,456
key2,abc
key2,cdf
key2,123
key2,456
key3,abc
key3,cdf
key3,123
key3,456

谢谢randomir,你的建议很有用。由于inter文件夹下的文件缺少换行符,导致内部循环无法工作。 - Ara
不客气。问题出在内部循环的read分割上。每一行从inter/$keyfile读取的内容都会被“分割”成一个变量。关键是要使用-a,将行分割成多个值并将它们存储在bash数组中。 - randomir
很棒的答案!IFS如何在嵌套的for循环中使用? - KargWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接