我在目录中有文件;它们使用YYYY_MM_DD命名:
-rw-r--r-- 1 root root 497186 Apr 21 13:17 2012_03_25
-rw-r--r-- 1 root root 490558 Apr 21 13:17 2012_03_26
-rw-r--r-- 1 root root 488797 Apr 21 13:17 2012_03_27
-rw-r--r-- 1 root root 316290 Apr 21 13:17 2012_03_28
-rw-r--r-- 1 root root 490081 Apr 21 13:17 2012_03_29
-rw-r--r-- 1 root root 486621 Apr 21 13:17 2012_03_30
-rw-r--r-- 1 root root 490904 Apr 21 13:17 2012_03_31
-rw-r--r-- 1 root root 491788 Apr 21 13:17 2012_04_01
-rw-r--r-- 1 root root 488630 Apr 21 13:17 2012_04_02
文件中的第一列是一个数字,我使用以下awk
命令获取第一列的平均值。
awk -F, '{ x += $1 } END { print x/NR }' MyFile
使用相同的命令我可以将两个文件传递给awk,以获得两个文件的总平均值。
awk -F, '{ x += $1 } END { print x/NR }' File1 File2
我想做的是......
我想获取目录中的所有文件,并按月分组,然后将当月的所有文件传递给awk命令。
因此,根据相同的数据,3月份有7个文件,我希望将所有7个文件传递给我的awk
命令,如下所示:
awk -F, '{ x += $1 } END { print x/NR }' File1 File2 File3 File4 File5 File6 File7
然后同样是四月的集合。
答案 0 :(得分:2)
您是否想以某种方式单独使用awk来完成此任务,或者您是否可以使用文件通配?例如:
awk -F, '{ #Do stuff }' 2012_03_[0-3][0-9]
将获取所有March文件。
你也可以使用2012_03*
,但它的通配模式不如上面那个具体。
修改强> 的
您可以使用这样的shell脚本:
DIR="/tmp/tmp"
for month in $(find "$DIR" -maxdepth 1 -type f | sed 's/.*\/\([0-9]\{4\}_[0-9]\{2\}\).*/\1/' | sort -u); do
awk -F, '#dostuff' "$DIR/${month}"_[0-3][0-9] > output/dir/SUM_"${month}"
done
与往常一样,有一些警告。带空格的文件会破坏它。如果文件中的YYYY_MM_DD格式不符合YYYY_MM_DD格式,则会出错,但不应影响性能。让我知道这些限制是否是不可接受的,我会再考虑一下。
答案 1 :(得分:1)
在Perl中你可以这样做:
#!/usr/bin/env perl
$dir = shift || ".";
opendir(DIR, $dir);
@files=grep (/\d{4}_\d{2}_\d{2}/, readdir(DIR));
foreach $file (@files)
{
($year_month) = $file =~ /(\d{4}_\d{2})/;
open(FILE, "<$dir/$file");
while($col = <FILE>)
{
$col =~ s/^(\d*)/\1/;
if($col)
{
$hash{"$year_month"}{"count"}++;
$hash{"$year_month"}{"sum"} += $col;
}
}
}
foreach $year_month (keys %hash)
{
$avg = $hash{"$year_month"}{"sum"} / $hash{"$year_month"}{"count"};
print "$year_month : $avg\n";
}
可以做得更短,但是这样你就有了一个很好的哈希数据结构,以防你以后想要以不同的方式计算它。请致电:
script.pl /path/to/dir
编辑:错误:忘记将目录添加到路径