#unix #reporting #awk
#unix #создание отчетов #awk
Вопрос:
У меня есть файл, содержащий расходы. Категории подобны дереву в том смысле, что категория может иметь несколько подкатегорий, которые могут иметь несколько подкатегорий и т.д. … например
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
Буду признателен за любую помощь.
Комментарии:
1. Это был вопрос с подвохом: посмотрим, удалим ли мы расходы itunes?
Ответ №1:
Как это?
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. Идеально, именно то, что я искал.
Ответ №2:
Ну, я не использую awk, но, возможно, это помогло бы:
cat input |
perl -e 'while (<>)
{ chomp; (undef, $bal, $cat) = split /,/; $tot{$cat} = 1.0 * $bal 0.0; }
map { print "$_: $tot{$_}n" } keys %tot; '
Ха, это заняло некоторое время (жизнь продолжается), но я вижу, что никто не опередил меня в этом?! Больше не могу оправдать использование этого oneliner…:
#!/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;
Ответ №3:
Сделайте это в командной строке: скрипт не нужен.Просто давайте сохраним это простым и понятными
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 '/,'
вывод:
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