1

ディレクトリにファイルがあります。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

同じコマンドを使用して、2つのファイルをawkに渡して、両方のファイルの合計平均を取得できます。

awk -F, '{ x += $1 } END { print x/NR }' File1 File2

私がやりたいのはこれです...

ディレクトリ内のすべてのファイルを取得し、それらを1か月ごとにグループ化してから、その月のすべてのファイルをawkコマンドに渡します。

同じデータによると、3月には7つのファイルがあり、7つのファイルすべてをawk次のようにコマンドに渡す必要があります。

awk -F, '{ x += $1 } END { print x/NR }' File1 File2 File3 File4 File5 File6 File7

それから同様に4月のセットのために。

4

2 に答える 2

2

どういうわけかawkだけでこれを達成したいですか、それともファイルグロブを使用できますか?例えば:

awk -F, '{ #Do stuff }' 2012_03_[0-3][0-9]

すべての3月のファイルを取得します。

使用することもできます2012_03*が、それは上記のものよりもグロブパターンでより具体的ではありません。

編集

次のようなシェルスクリプトを使用できます。

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形式に準拠していないファイルがある場合はエラーが発生しますが、パフォーマンスには影響しません。これらの制約が受け入れられない場合はお知らせください。もう少し考えます。

于 2012-04-21T19:36:23.217 に答える
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

編集:バグ:パスにディレクトリを追加するのを忘れた

于 2012-04-21T19:47:40.963 に答える