Bash 基于时间戳将文件拆分为时间段文件

Bash 基于时间戳将文件拆分为时间段文件,bash,unix,awk,timestamp,Bash,Unix,Awk,Timestamp,我有数千个log.txt文件,它们的名称或顺序无关紧要,最终输出文件中的条目顺序也无关紧要,这些文件由unix时间戳和值组成,例如: infile1.txt: 1361775157 a 1361775315 b 1379007707 c 1379014884 d infile2.txt: 1360483293 e 1361384920 f 1372948120 g 1373201928 h 我的目标是将它们划分为任意定义的时间间隔,例如,在本例中,以136000000

我有数千个log.txt文件,它们的名称或顺序无关紧要,最终输出文件中的条目顺序也无关紧要,这些文件由unix时间戳和值组成,例如:

infile1.txt:
1361775157 a
1361775315 b            
1379007707 c
1379014884 d

infile2.txt:
1360483293 e
1361384920 f
1372948120 g
1373201928 h
我的目标是将它们划分为任意定义的时间间隔,例如,在本例中,以1360000000、137000000和138000000000为边界,以便获得与时间间隔一样多的文件:

1360000000-1370000000.txt:
1361775157 a 
1361775315 b    
1360483293 e
1361384920 f        

1370000000-1380000000.txt:
1379007707 c
1379014884 d
1372948120 g
1373201928 h
我当前的方法是运行一个脚本,将循环中每个时段的条目作为第一个和第二个参数进行过滤,并将其添加到文件中:

#!/bin/bash

for i in *txt; do
    awk -v t1=$1 -v t2=$2 '$1 >= t1 && $1 < t2' $i >> "elsewhere/$1-$2.txt"
done

然而,这意味着每个时间段都会读取所有文件,这在我看来效率很低。有没有办法只读取一次每个文件,并将每一行附加到与其时间段对应的文件中?

我会使用以下方法:

$ cat tst.awk
{
    bucket = int($1/inc)
    print $0 " > " ( (inc*bucket) "-" (inc*(bucket+1)-1) ".txt" )
}

$ awk -v inc='10000000' -f tst.awk file1 file2
1361775157 a > 1360000000-1369999999.txt
1361775315 b > 1360000000-1369999999.txt
1379007707 c > 1370000000-1379999999.txt
1379014884 d > 1370000000-1379999999.txt
1360483293 e > 1360000000-1369999999.txt
1361384920 f > 1360000000-1369999999.txt
1372948120 g > 1370000000-1379999999.txt
1373201928 h > 1370000000-1379999999.txt
如果您使用的是GNU awk,它可以在需要时为您关闭/重新打开文件,那么只需在测试完成时将$0>更改为>,否则请执行以下操作:

{
    bucket = int($1/inc)
    if ( bucket != prev ) {
        close(out)
        out = (inc*bucket) "-" (inc*(bucket+1)-1) ".txt"
        prev = bucket
    }
    print >> out
}

要在任何awk中工作。

我会使用以下方法:

$ cat tst.awk
{
    bucket = int($1/inc)
    print $0 " > " ( (inc*bucket) "-" (inc*(bucket+1)-1) ".txt" )
}

$ awk -v inc='10000000' -f tst.awk file1 file2
1361775157 a > 1360000000-1369999999.txt
1361775315 b > 1360000000-1369999999.txt
1379007707 c > 1370000000-1379999999.txt
1379014884 d > 1370000000-1379999999.txt
1360483293 e > 1360000000-1369999999.txt
1361384920 f > 1360000000-1369999999.txt
1372948120 g > 1370000000-1379999999.txt
1373201928 h > 1370000000-1379999999.txt
如果您使用的是GNU awk,它可以在需要时为您关闭/重新打开文件,那么只需在测试完成时将$0>更改为>,否则请执行以下操作:

{
    bucket = int($1/inc)
    if ( bucket != prev ) {
        close(out)
        out = (inc*bucket) "-" (inc*(bucket+1)-1) ".txt"
        prev = bucket
    }
    print >> out
}

要在任何awk中工作。

请将您的问题显示为输入文件的一些示例内容,以显示unixtimestamp的外观。还显示如何指定时间范围以及文件名的外观。文件名是否与文件顺序一致?感谢您的回复!我已经添加了更多的信息,希望这些信息能让我更清楚地了解我的目标。我认为我应该将所有内容存储在一个sqlite数据库中,并在时间戳列上添加索引,而不是一堆文本文件。这使得从时间戳介于:start_time和:end_time之间的消息中获取任意间隔变得微不足道,从而允许在时间范围之上进行更复杂的查询,一个文件比数千个文件更容易管理。您应该修复所需的输出文件名,使137000000不是多个文件名的一部分,特别是不是不能显示在其中的文件名的一部分。您真的想调用一个包含1360000001370000013800000000等边界列表的脚本,还是只想说从1360000000开始每10000000,或从1360000000到9750000000或类似的每10000000?请您的问题显示输入文件的一些示例内容,这显示了unixtimestamp的外观。还显示如何指定时间范围以及文件名的外观。文件名是否与文件顺序一致?感谢您的回复!我已经添加了更多的信息,希望这些信息能让我更清楚地了解我的目标。我认为我应该将所有内容存储在一个sqlite数据库中,并在时间戳列上添加索引,而不是一堆文本文件。这使得从时间戳介于:start_time和:end_time之间的消息中获取任意间隔变得微不足道,从而允许在时间范围之上进行更复杂的查询,一个文件比数千个文件更容易管理。您应该修复所需的输出文件名,使137000000不是多个文件名的一部分,特别是不是不能显示在其中的文件名的一部分。您真的想调用一个包含1360000001370000013800000000等边界列表的脚本,还是只想说从1360000000开始每隔10000000,或者从1360000000到9750000000或类似的值每隔10000000?