bash扫描数百万个文件并快速扫描值

时间:2012-12-02 14:06:31

标签: bash shell

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

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

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

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分钟左右。我可以进一步改进吗?

2 个答案:

答案 0 :(得分: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可能是足够,并确保运行得更快。

答案 1 :(得分:1)

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