首页 > 解决方案 > 使用 GNU sed (gsed) “查找”的 Bash 脚本的输出文件为空

问题描述

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

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”来检查。即,我可以在屏幕上看到“查找”的输出,并且“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文件。

标签: bashfilesediognu-sed

解决方案


grep 的默认行为是打印出匹配的行。使用 sed 太过分了。

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

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

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

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

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

推荐阅读