создать сумму вложенных категорий с помощью awk - PullRequest
1 голос
/ 22 апреля 2011

У меня есть файл с расходами.Категории имеют древовидную структуру в том смысле, что категория может иметь несколько подкатегорий, которые могут иметь несколько подкатегорий и т. Д. Например,

2011-02-01,-4.00,entertainment/itunes
2011-02-02,-5.00,entertainment/food/dinner
2011-02-03,-6.00,entertainment/food/take-away/thai
2011-02-04,-7.00,entertainment/food/take-away/indian
2011-02-05,-8.00,entertainment/books/kindle
2011-02-05,-8.00,entertainment/books/kindle
2011-02-06,-9.00,entertainment/books/real

Я хотел бы использовать awk для создания отчета, в котором подытоживаются всеузел в дереве категорий.

например,

entertainment:-47.00
entertainment/books:-25.00
entertainment/books/kindle:-16.00
entertainment/books/real:-9.00
entertainment/food:-18.00
entertainment/food/take-away:-13.00
entertainment/food/take-away/indian:-7.00
entertainment/food/take-away/thai:-6.00

Любая помощь будет оценена.

Ответы [ 3 ]

1 голос
/ 23 апреля 2011

Как это?

awk -F, '{
     tots["/"$3]+=$2
     n=split($3, tmpT, "/")
     key="/"
     for (i=1;i<n;i++) {
         key  = ( key == "/" ) ? key tmpT[i]  : key "/"  tmpT[i]
         tots[key]+=$2
     }
 }
 END{
     for (t in tots) print t "\t" tots[t]
 }' testData.txt | sort -u

**Output**
/entertainment  -47       
/entertainment/books    -25
/entertainment/books/kindle     -16
/entertainment/books/real       -9
/entertainment/food     -18
/entertainment/food/dinner      -5
/entertainment/food/take-away   -13
/entertainment/food/take-away/indian    -7
/entertainment/food/take-away/thai      -6
/entertainment/itunes   -4

Каждый подузел это подытог.

Не уверен, что это критическая вещь.

Надеюсь, это поможет.

1 голос
/ 23 апреля 2011

Сделайте это в командной строке: Нет необходимости в скрипте. Просто давайте сделаем его простым и понятным

awk -F",|/" '{a[$3]+=$2;
              b[$3"/"$4]+=$2;
              c[$3"/"$4"/"$5]+=$2;
              d[$3"/"$4"/"$5"/"$6]+=$2}
          END{for (i in a) print i","a[i];
              for (j in b) print j","b[j];
              for (k in c) print k","c[k];
              for (l in d) print l","d[l];}' file.txt|grep -v '/,'

Ouput:

entertainment,-47
entertainment/books,-25
entertainment/itunes,-4
entertainment/food,-18
entertainment/books/kindle,-16
entertainment/books/real,-9
entertainment/food/take-away,-13
entertainment/food/dinner,-5
entertainment/food/take-away/thai,-6
entertainment/food/take-away/indian,-7
1 голос
/ 22 апреля 2011

Ну, я не делаю awk, но, возможно, это поможет:

cat input |
  perl -e 'while (<>) 
     { chomp; (undef, $bal, $cat) = split /,/; $tot{$cat} += 1.0 * $bal + 0.0; } 
     map { print "$_: $tot{$_}\n" } keys %tot; '

Ха, что заняло некоторое время (жизнь продолжается), но я не вижу, чтобы никто не побил меня этим ?!На самом деле не могу больше оправдать превращение этого единоличного ...:

#!/usr/bin/perl
use strict;
use warnings;

my %tot;

while (<>) 
{ 
    chomp; 
    my (undef, $bal, $cat) = split /,/; 
    my @subs = split (qr(/), $cat);

    $tot{$_} += ($bal+0.0) 
        foreach (map { join('/', @subs[0..$_]) } (0 .. $#subs))
} 

map { print "$_: $tot{$_}\n" } sort keys %tot;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...