为什么循环输出的重定向取决于文件名?

为什么循环输出的重定向取决于文件名?

我有两个文件:a.csvb.csv

echo $'a_header\na1' > a.csv
echo $'b_header\nb1' > b.csv

现在我想删除每行的第一行,然后将它们连接起来。

for file in `ls *.csv`; do cat $file | tail -n +2 | cat; done 

但是,当我将上一个命令的输出重定向到文件时,根据输出文件的名称,我会得到不同的结果。

for file in `ls *.csv`; do cat $file | tail -n +2 | cat; done > result
for file in `ls *.csv`; do cat $file | tail -n +2 | cat; done > result.csv

cat result
a1
b1

cat result.csv
a1
b1
b1

答案1

如果有以下命令:

command > file

命令的标准输出 (fd 1)command被重定向到文件file.如果该文件不存在,则创建该文件。命令通常将其命令输出重定向到文件描述符 1 (stdout)。

当使用上述表达式(其中输出重定向到文件)时,该文件必须在输出流启动之前存在。因此bash创建文件(空)并连接到 stdout command,然后开始在该文件描述符上写入。

这是由外壳处理的。该命令不知道它是否写入匿名管道或文件。


给出这个命令:

for file in `ls *.csv`; do cat $file | tail -n +2 | cat; done > result.csv

这里发生的情况是文件result.csv被创建为空。然后for循环遍历每个结尾为csv(包括result.csv)的文件。a.csv然后b.csv至少会处理文件result.csvresult.csvthen 中的第二行b1。这就是结果文件中有两行的原因。

相关内容