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



我在一个文件夹(嵌套)中有数百万个文件。我需要扫描这些文件中的一个值,并打印包含该值的行(比如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分钟。我能进一步改进吗?

在我看来,减少脚本开销会让事情更快。

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可能就足够了,而且运行速度肯定会更快。

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

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

相关内容

  • 没有找到相关文章

最新更新