2012-04-21 12 views
1

У меня есть файлы в каталоге; они именуются YYYY_MM_DD:Групповые файлы и команда pipe to awk

-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 ,

Так, согласно тем же данным, есть 7 файлов в марте, я хочу, чтобы все 7 файлов, которые будут переданы моей awk команды, как это:

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

Тогда также для набора в апреле.

+0

Как вы собираетесь решить, какие месяцы должны быть обработаны? Будет ли это вызов команды чем-то вроде 'month_stats 2012-03 2012-04'? Или вам нужно будет сканировать все файлы в каталоге, чтобы узнать, какие месяцы представлены для их обработки? –

ответ

2

Вы хотите каким-то образом выполнить это с помощью awk в одиночку или использовать файловое подталкивание? Например:

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

получит все файлы в марте.

Вы также можете использовать 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, но это не должно влиять на производительность. Дайте мне знать, если эти ограничения неприемлемы, и я подумаю об этом немного больше.

+0

Это будет нормально, но я хочу просто указать на каталог и выяснить, сколько месяцев есть и обрабатывать каждый месяц как пакет, если вы меня понимаете. Здесь много лет, поэтому 2012_04_11 и 2011_04_11 могут существовать. –

+0

Смотрите мои правки выше. –

+0

yeh должно быть хорошо, я буду играть, когда у меня есть время и дам вам знать. Благодарю. –

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 

EDIT: ошибка: забыл добавить каталог в путь