对于使用 GNU sed (gsed) 执行"find"的 Bash 脚本的输出文件为空



我有很多文件,每个文件都在一个目录中。我的脚本应该:

  • 在文件中查找字符串。假设文件称为"结果",字符串称为"平均"。

  • 然后将字符串行上的其他所有内容附加到另一个名为"allResults"的文件中。运行脚本后,文件"allResults"应包含与"结果"文件一样多的行,例如

allResults.txt(我想要的):

Everything on the same line as the string, "average" in directory1/results
Everything on the same line as the string, "average" in directory2/results
Everything on the same line as the string, "average" in directory3/results
...
Everything on the same line as the string, "average" in directory-i/results

我的脚本可以找到我需要的东西。我已经通过在脚本正常工作时对"allResults.txt"做一个"cat"并在"allResults.txt的父目录上做一个"ls -l"来检查。 也就是说,我可以在屏幕上看到"find"的输出,"allResults.txt"的大小短暂增加,然后回到0。 问题是脚本完成后"allResults.txt"为空。 因此,"查找"的结果不会被追加/添加到"allResults.txt。它们正在被覆盖。 这是我的脚本(我使用"gsed",GNU sed,因为我是Mac OSX Sierra用户):

#!/bin/bash
# Loop over all directories, find.
let allsteps=100000
for ((step=0; step <= allsteps; step++)); do
i=$((step));
findme="average"
find ${i}/experiment-1/results.dat -type f -exec gsed -n -i "s/${findme}//p" {} ; >> allResults.txt
done 

请注意,我在这里的示例中使用了">>",因为我读到它附加(这就是我想要的 - 与我从所有文件中"查找"匹配的所有行的列表),而">"覆盖。 但是,在这两种情况下(当我使用">"或">>"时),我最终都会得到一个空的allResults.txt文件。

grep的默认行为是打印出匹配的行。使用 sed 是矫枉过正。

您也不需要显式循环。事实上,过度循环是一种常见的比喻,程序员倾向于从循环常见的其他语言中导入。大多数 shell 命令和构造接受多个文件名。

grep average */experiment-1/results.dat > allResults.txt

这样做的好处是输出文件只打开一次,一举写入。

如果确实有数十万个文件要处理,则可能会遇到命令行长度限制。如果发生这种情况,您可以切换到find调用,这将确保不要一次调用包含太多文件的 grep。

find . -name results.dat -exec grep average {} + > allResults.txt

最新更新