我努力实现报道练习的自动化,并希望得到一些指示或建议。
我有几十万个小(<5kb)文本文件。每个都包含一些变量,我需要计算匹配每个变量组合的文件数。
每个文件都包含设备编号,例如/ 001 / /002 /.../006/。
每个文件还包含一个日期字符串,例如01.10.14(dd.mm.yy)
某些文件包含&#39;状态&#39;字符串总是&#34;未结算&#34;
我需要一种方法来浏览Linux系统上的每个文件(分布在几个子目录中),并生成一个按设备计算的报告文件&#39;每个日期戳(6个月范围)包含多少个文件,每个日期包含状态字符串。
报告可能如下所示: 设备,日期,文件总数 设备,日期,总数&#34;未结算&#34;计数
e.g。
/001/, 01.12.14, 356
/001/, 01.12.14, 12
/001/, 02.12.14, 209
/001/, 02.12.14, 8
/002/, 01.12.14, 209
/002/, 01.12.14, 7
等等
换句话说:
Foreach /device/
Foreach <date>
count total matching files - write number to file
count toal matching 'not settled' files - write number to file
要匹配的每个字符串都可以出现在文件中的任何位置。
我尝试使用grep管道输入第二个(和第三个)grep命令,但是我想自动执行此操作并循环遍历变量(6个设备,大约180个日期,2个状态字符串)。我怀疑Perl和Bash是答案,但我不在我的深处。
任何人都可以推荐一种方法吗?
编辑:评论中提到的一些示例数据。该信息基本上是来自收据的收据数据 - 如将被发送到打印机。这是一个示例(识别出去除的位)。
c0! SUBTOTAL 11.37
c0! ! T O T A L 11.37!
c0! 19 ITEMS
c0! C a s h ? 11.37
vu p022c0!
c0! NET TOTAL VAT A 10.87
c0! VAT 00.0% 0.00
c0! NET TOTAL VAT B 0.42
c0! VAT 20.0% 0.08
c0! *4300 772/080/003/132 08.01.15 11:18 A-00
Contents = Not Settled
在上面的例子中,我正在寻找/ 003 /,08.01.15和&#34;未定居&#34;
非常感谢。
答案 0 :(得分:1)
首先,将所有内容读入SQLite数据库,然后针对您的内容运行查询。如果您需要调整任何内容,将数据放入SQL数据库将节省您的时间。此外,如果您设置了正确的表,即使是简单的SQL也可以解决这类问题。
答案 1 :(得分:1)
首先,我同意@Sinan :-)
以下内容可能会起到黑客攻击文件数据的作用。
# report.pl
use strict;
use warnings;
use Data::Dumper;
my %report;
my ($date, $device) ;
while (<>) {
next unless m/^ .*
(?<device>\/00[1-3]\/) .*
(?<date>\d{2}\.\d{2}\.\d{2})
.*$/x ;
($date, $device,) = ($+{date}, $+{device});
$_ = <> unless eof;
if (/Contents/) {
$report{$date}{$device}{"u_count"}++ ;
}
else {
$report{$date}{$device}{"count"}++ ;
}
}
print Dumper(\%report)
这似乎与下面显示的格式的数据文件集合一起使用(因为您没有说明或显示Contents = Not Settled
出现的位置,我认为它是 的一部分最后一行以及每个文件的单独最后一行中的设备ID 或。)
<强>解释强>:
该脚本读取在while(<>){}
循环中作为glob传递的所有文件的STDIN。首先,next unless m/ ...
跳过前面的输入行,直到它与具有设备和日期信息的行匹配。
接下来,匹配使用named capture groups(?<device> ?<date>
来保存找到的模式的值,并将这些值放在相应的变量(($date, $device,) = ($+{date}, $+{device});
)中。这些可能只是是$1
和$2
但是命名让我在这里组织起来。
然后,如果有另一行要阅读$_ = <> unless eof;
,请阅读并尝试最后一组条件匹配,以便添加到$counts
和$u_counts
。
数据文件格式:
file1.data
c0! SUBTOTAL 11.37
c0! ! T O T A L 11.37! c0! 19 ITEMS
c0! C a s h ? 11.37
vu p022c0!
c0! NET TOTAL VAT A 10.87
c0! VAT 00.0% 0.00
c0! NET TOTAL VAT B 0.42
c0! VAT 20.0% 0.08
c0! *4300 772/080/003/132 08.01.15 11:18 A-00
file2.data
c0! SUBTOTAL 11.37
c0! ! T O T A L 11.37! c0! 19 ITEMS
c0! C a s h ? 11.37
vu p022c0!
c0! NET TOTAL VAT A 10.87
c0! VAT 00.0% 0.00
c0! NET TOTAL VAT B 0.42
c0! VAT 20.0% 0.08
c0! *4300 772/080/002/132 08.01.15 11:18 A-00
Contents = Not Settled
(此处列出了一组用于测试的文件:http://pastebin.com/raw.php?i=7ALU80fE)。
perl report.pl file*.data
Data::Dumper
输出:
$VAR1 = {
'08.01.15' => {
'/002/' => {
'u_count' => 4
},
'/003/' => {
'count' => 1
}
},
'08.12.15' => {
'/003/' => {
'count' => 1
}
}
};
通过使用keys()
(日期)迭代哈希并检索每台机器的内部哈希值和计数值,您可以生成报告。真的,最好有一些测试来确保一切按预期工作 - 或者只是像@sinan_Ünür建议的那样:使用SQLite!
NB :此代码未经过广泛测试: - )