3

我在一个文件夹(嵌套)中有数百万个文件。我需要从这些文件中扫描一个值并打印包含该值的行(比如LINE_TXT)。早些时候,我曾经对每个文件进行 sed,但过去需要 45 分钟才能完成此操作。我之前的解决方案是这样的:

FILES=$(find $1 -type f -name 'filename.txt')
for f in $FILES
do
    if [[ "$LINE" == *LINE_TXT* ]]; then
        echo $LINE
    fi
done

我发现 pipemill 是实现这一目标的最佳方式。我的主要解决方案是这样的:

makefifo mypipe
find $1 -type f -name 'filename.txt' | xargs cat > my pipe &
while read -r LINE
do
    if [[ "$LINE" == *LINE_TXT* ]]; then
        echo $LINE
    fi
done << mypipe

运行时间约为 1 分钟。我可以进一步改进吗?

4

3 回答 3

5

在我看来,更少的脚本开销会使事情变得更快。

fgrep -r -h 'LINE_TXT' $1

只需让 grep 使用-r. 如果您不希望其输出在其输出中包含文件名,请包含该-h选项。您可以通过后处理所需的任何内容来管道其输出。

如果您只想搜索特定文件名,则 grep 的-r选项有其自己的选项:--include--exclude,在其手册页中提到。例如:

fgrep -h -r --include '*/filename.txt' 'LINE_TXT' $1

尽管该find命令非常出色,并且在某些情况下非常宝贵,但如果您可以使用内置于单个工具(如 )中的选项grep,您将产生更少的开销。该find命令不查看文件内部,因此它仍然必须grep为每个文件启动。如果您确实想使用find,它可能看起来像这样:

find $1 -name 'filename.txt' -exec fgrep 'LINE_EXT' {} \;

这样做的好处是让您可以访问find的目录搜索功能,但如果您只想在目录树中查找一个特别命名的文件,那么 grep-r --include可能就足够了,而且运行速度肯定会更快。

于 2012-12-02T14:15:17.070 回答
1

是的find $1 -type f -name 'filename.txt' | xargs fgrep LINE_TXT,如果您只想在任何这些文件中找到“LINE_TXT”的所有匹配项。

于 2012-12-02T14:09:13.740 回答
0

这是工具ackagripgrep的确切用例。它们不仅比 使用起来更方便grep -r,而且至少后两者也快得多。

于 2021-12-16T06:52:19.747 回答