Bash 从一个文件的结尾到开头的更快的方式?

Bash 从一个文件的结尾到开头的更快的方式?,bash,awk,tac,Bash,Awk,Tac,我希望从文件的底部开始得到结果,然后一直工作到开始。我尝试使用tac并将其导入我的awk命令,但对于2GB文件来说,这非常慢15秒。与搜索同一文件通常需要3秒相比。我还将awk命令传输到tail-n+1 | head-n50中,以在50个结果之后停止 有没有更快的方法来整理文件?或者至少从下至上开始搜索 最重要的是创建一个python脚本,该脚本包含参数开始日期、结束日期和搜索词,并使用这些参数在有日期组织的日志文件中进行搜索。一次返回50个结果 我需要从头到尾阅读,以防用户希望按从最新日期到最

我希望从文件的底部开始得到结果,然后一直工作到开始。我尝试使用tac并将其导入我的awk命令,但对于2GB文件来说,这非常慢15秒。与搜索同一文件通常需要3秒相比。我还将awk命令传输到tail-n+1 | head-n50中,以在50个结果之后停止

有没有更快的方法来整理文件?或者至少从下至上开始搜索

最重要的是创建一个python脚本,该脚本包含参数开始日期、结束日期和搜索词,并使用这些参数在有日期组织的日志文件中进行搜索。一次返回50个结果

我需要从头到尾阅读,以防用户希望按从最新日期到最旧日期的降序进行搜索

将结果的“最旧”升序为“最新”的示例命令: im使用find,因为它是用户指定的参数,所以它可能引用所有文件*.txt

开始日期:2018-03-04T03:45 结束日期:2018-03-05T16:24 搜索词:马铃薯
查找'/home/logs/'-type f-name'log_file.txt'-exec cat{}\+2>&1|LANC=C fgrep'Potato'\124; LC|u ALL=C IGNORECASE=1 awk-v start=2018-03-04T03:45:00-v stop=2018-03-05T16:24:59'BEGIN{line=0;xz=fori=4;i=start&&1如果您有内存,请在末尾部分向后散列记录和进程:


更新:我在上面测试了一个1 GB的文件36 M记录。它在1分钟内被散列和计数,并占用了大约4.5 GB的内存。

好吧,如果你有内存,在结尾部分对记录进行散列并向后处理:


更新:我在上面测试了一个1 GB文件36 M记录。它在1分钟内被散列和计数,占用了大约4.5 GB内存。

一切都取决于您使用的awk代码,但想到的一些解决方案是:

如果打印每一行:

tac <file> | awk '(NR > 50){exit}{do-your-stuff}'

两种解决方案都在前50个打印行之后终止awk。这样,您就不必处理完整的2GB文件。50个打印行之后的终止模拟尾部-n+1 | head-n 50

一切都在一定程度上取决于您拥有的awk代码,但想到的一些解决方案是:

如果打印每一行:

tac <file> | awk '(NR > 50){exit}{do-your-stuff}'

两种解决方案都在前50个打印行之后终止awk。这样,您就不必处理完整的2GB文件。50个打印行之后的终止模拟了tail-n+1 | head-n 50

打开文件的速度要快得多,并在文件结束之前查找到一定数量。Perl在这里很方便:

perl -Mautodie -se '
    $size = -s $file;
    $blocksize = 64000;
    open $fh, "<", $file;
    seek $fh, $size - $blocksize, 0;
    read $fh, $data, $blocksize;
    @lines = split "\n", $data;
    # last 50 lines
    print join "\n", reverse @lines[-51..-1];
' -- -file="filename"
我们可以在那里抛出一个循环,这样在它读取最后一个块之后,它可以寻找到减去2个块的末尾,然后读取一个块,以此类推


但是,如果您想从下到上处理整个庞大的文件,您必须预计它需要时间。

打开文件的速度要快得多,并在文件结束前查找到一定数量。Perl在这里很方便:

perl -Mautodie -se '
    $size = -s $file;
    $blocksize = 64000;
    open $fh, "<", $file;
    seek $fh, $size - $blocksize, 0;
    read $fh, $data, $blocksize;
    @lines = split "\n", $data;
    # last 50 lines
    print join "\n", reverse @lines[-51..-1];
' -- -file="filename"
我们可以在那里抛出一个循环,这样在它读取最后一个块之后,它可以寻找到减去2个块的末尾,然后读取一个块,以此类推


但是,如果你想从下到上处理整个庞大的文件,你就必须期望它需要时间。

我是否正确地理解你这样做:tac | awk'stuff'| tail-n+1 | head-n50?如果是,为什么是tail-n+1?为了帮助你,我们需要更多地了解你的awk脚本。你能解释一下你的想法吗需要这个吗?如果tac方法表现良好,你会在awk主体中放置什么?描述一下你需要做什么才能让你想以相反的顺序阅读文件。我是否正确地理解你这样做:tac | awk'stuff'| tail-n+1 | head-n50?如果是,为什么是tail-n+1?为了帮助你,我们将需要更多地了解您的awk脚本。您能解释一下您需要它做什么吗?如果tac方法能够很好地执行,您会在awk正文中添加什么?描述一下您需要做什么才能使您希望以相反的顺序读取文件。