1

我有一些每小时获取的数据文件。它们的文件名如下所示:

20120101-00.raw
20120101-01.raw
...
YYYYMMDD-HH.raw

我必须将每小时文件聚合到每天、每天到每月等。聚合脚本的语法如下:

aggregate output-file input-file1 input-file2 ...

聚合的模式是:

20120101-[0-2][0-9].raw -> 20120101.raw
201201[0-3][0-9].raw -> 201201.raw
etc.

我正在尝试编写 Makefile 来自动化流程,但我完全陷入困境 - 我不知道如何处理扩展问题 - 源文件和目标文件具有相同的扩展名。我用:

$(shell find . -type f | grep -e "\.raw1$$" | cut -c 8 | sort -u )

查找我必须生成的文件。

4

2 回答 2

1

如果我为此编写了一个脚本,它将读取 .raw 文件名列表,对列表进行排序,通过删除最后两位数字为每个文件名创建一个缩短的名称,如果这个缩短的名称与以前的缩短的名称相同,添加要聚合的列表的完整文件名,如果缩短的名称与之前的缩短的名称不同,则根据添加到列表中的最后一个条目创建输出文件名,如果输出文件已经存在并且比添加的最后一个条目更新到列表什么都不做,因为它已经是最新的,否则使用输出文件名和输入文件列表运行聚合命令。

要使用该脚本,首先使用所有每小时文件运行它,然后使用所有每日文件再次运行它,(如果需要,它可以使用所有每月文件再次运行以生成年度文件。)

概述的脚本有一些限制:

  1. 一次只能提供一种文件类型的列表(例如,每小时、每天)
  2. 要聚合的每个组中的所有文件都需要位于同一目录中,或者初始排序只需要使用文件名的基本名称(而不是目录)部分作为排序键。
  3. 如果这些是可能在脚本运行时更新的日志文件,则可能会丢失聚合命令运行时记录的数据。这是因为输出文件上的时间戳(用于确定相对于输入文件是否是最新的)是聚合完成的时间,而不是它开始的时间。一种解决方法是在开始聚合之前触摸时间戳文件(基于输出文件名),并使用时间戳文件而不是输出文件来确定输出文件是否是最新的。
于 2012-04-06T00:44:17.217 回答
0

我同意 Oli Charlesworth 的观点,即 Make 不是这项工作的最佳工具——我会使用 Perl 脚本。但是如果你想使用Make,它是可以做到的。这是使用对sed. 它可以收紧一点,但我会追求可读性。

FILES := $(shell ls *-??.raw)

DAYS :=   $(sort $(shell ls *-??.raw | sed 's/\(........\).*/\1.raw/'))
MONTHS := $(sort $(shell ls *-??.raw | sed 's/\(......\).*/\1.raw/'))
YEARS :=  $(sort $(shell ls *-??.raw | sed 's/\(....\).*/\1.raw/'))

all.raw: $(YEARS)
    aggregate $@ $^

$(YEARS): %.raw : $(MONTHS)
    aggregate $@ $(filter $*%, $^)

$(MONTHS): %.raw : $(DAYS)
    aggregate $@ $(filter $*%, $^)

$(DAYS): %.raw :
    aggregate $@ $(filter $*%, $(FILES))
于 2012-04-06T13:21:58.090 回答