首页 > 解决方案 > 通过脚本循环一个目录中的所有 .csv 文件,并将每个循环的结果输出到不同目录中的一个单独的 .csv 中

问题描述

我正在努力通过脚本从一个目录运行多个 .csv 文件,并将每个文件的输出发送到不同的目录。我能够一个一个地运行 .csv 文件,但我有 100 个文件需要通过脚本。单独来说,这很简单,我从中提取 .csv 文件Test_Folder并将脚本的输出发送到Results

bash run_example.sh Test_Folder/df1.csv >> Results/results1.csv

但是当我尝试为它们都运行一个循环时,由于目录不同,我遇到了一些错误。我尝试了一些不同的东西:

for csvfile in Test_Folder/*.csv;
do
    bash run_example.sh $csvfile >> Results/test_results.csv
done

这显然有效,但test_results.csv在每次循环后都会被覆盖。

for csvfile in Test_Folder/*.csv;
do
    bash run_example.sh $csvfile >> "Results/results_${csvfile}.csv"
done

在尝试运行上述内容时,我遇到了:

bash: Results/results_Test_Folder/df1.csv.csv: No such file or directory

因此,它似乎采用的路径$csvfile不仅仅是文件本身。这最终会搜索一个明显不存在的目录。我尝试了上述代码的其他一些变体,使用其他 SE 帖子作为参考,但我没有看到任何专门提到不同目录的帖子。

我正在寻找与results.csv输入文件相同数量的文件填充的新目录,所以results1.csvresults2.csv等等。即使是像每个循环递增并添加到输出文件名的数字这样简单的东西也是完美的。任何指导将不胜感激!

标签: bash

解决方案


假设评论解决了您的问题,为了完整起见,您遇到的问题是由于csvfile包含路径信息的循环变量Test_Folder/。当您重定向到 时Results/results_${csvfile}.csv,您实际上是重定向到,例如Results/results_Test_Folder/df1.csv.csv。你没有Test_Folder/从前面修剪的地方csvfile,你已经应用了.csv两次扩展。这会导致您的确切错误:

bash: Results/results_Test_Folder/df1.csv.csv: No such file or directory

要纠正这个问题,您可以使用带有子字符串删除的参数扩展Test_Folder/从前面进行修剪,csvfile并且由于文件名已经具有.csv扩展名,只需省略它,例如

for csvfile in Test_Folder/*.csv;
do
    bash run_example.sh "$csvfile" >> "Results/results_${csvfile#Test_Folder/}"
done

这将导致您给出的示例重定向df1.csv到:

Results/results_df1.csv

注意:你应该引用原文$csvfilebash run_example.sh "$csvfile" ...

POSIX 提供的带有子字符串删除的标准参数扩展是:

${var#pattern}      Strip shortest match of pattern from front of $var
${var##pattern}     Strip longest match of pattern from front of $var
${var%pattern}      Strip shortest match of pattern from back of $var
${var%%pattern}     Strip longest match of pattern from back of $var

注意,bash 本身提供了很多很多很多。请参阅参数扩展标题下的man 1 bash 。

如果您还有其他问题,请仔细查看并告诉我。


推荐阅读