timestamp : IDs returned
20160420084726:-
20160420085418:[111783178, 111557953, 111646835, 111413356, 111412662, 105618372, 111413557]
20160420085418:[111413432, 111633904, 111783198, 111792767, 111557948, 111413225, 111413281]
20160420085418:[111413432, 111633904, 111783198, 111792767, 111557948, 111413225, 111413281]
20160420085522:[111344871, 111394583, 111295547, 111379566, 111352520]
20160420090022:[111344871, 111394583, 111295547, 111379566, 111352520]
타임스탬프 형식은 YYYYMMDDhhmmss입니다.
· 광고는 대괄호로 묶인 광고 자산 ID의 쉼표로 구분된 목록입니다. 또는 - 광고가 반환되지 않은 경우
하루 중 10분마다 출력하는 스크립트를 작성해야 합니다.
반환된 ID 수
반환된 고유 ID 수
스크립트는 고유 ID 또는 전체 ID를 제공해야 하는지 여부를 선택하는 명령줄 매개변수를 지원해야 합니다.
위의 로그 발췌를 사용한 출력 예(총계 모드):
20160420084:0
20160420085:26
20160420090:5
고유 계산 모드에서는 다음을 제공합니다.
20160420084:0
20160420085:19
20160420090:5
이것이 내가 지금까지 가지고 있는 것입니다:
#!/usr/bin/bash
awk -F":" ' { print $1":" $2 } ' file.log | sort -r | uniq -c
결과:
1 20160420090022:[111344871, 111394583, 111295547, 111379566, 111352520]
1 20160420085522:[111344871, 111394583, 111295547, 111379566, 111352520]
1 20160420085418:[111783178, 111557953, 111646835, 111413356, 111412662, 105618372, 111413557]
2 20160420085418:[111413432, 111633904, 111783198, 111792767, 111557948, 111413225, 111413281]
1 20160420084726:-
7: –
답변1
배열의 배열을 처리하려면 GNU awk를 사용하십시오( length(array)
그러나 현재 대부분의 awk는 이를 수행합니다):
$ cat tst.awk
BEGIN { FS=OFS=":" }
NR>1 {
time = substr($1,1,11)
totIds[time] += 0
if ( gsub(/[][ ]/,"",$2) ) {
totIds[time] += split($2,ids,/,/)
for ( i in ids ) {
unqIds[time][ids[i]]
}
}
}
END {
for ( time in totIds ) {
print time, ( type ~ /^tot/ ? totIds[time] : length(unqIds[time]) )
}
}
$ awk -v type='tot' -f tst.awk file
20160420084:0
20160420085:26
20160420090:5
$ awk -v type='unq' -f tst.awk file
20160420084:0
20160420085:19
20160420090:5
GNU awk가 없다면 코드와 메모리 사용량이 약간만 늘어나서 같은 작업을 수행하기 위해 awk를 사용할 수 있습니다.
$ cat tst.awk
BEGIN { FS=OFS=":" }
NR>1 {
time = substr($1,1,11)
totIds[time] += 0
if ( gsub(/[][ ]/,"",$2) ) {
totIds[time] += split($2,ids,/,/)
for ( i in ids ) {
if ( !seen[time,ids[i]]++ ) {
numUnq[time]++
}
}
}
}
END {
for ( time in totIds ) {
print time, ( type ~ /^tot/ ? totIds[time] : numUnq[time]+0 )
}
}
$ awk -v type='tot' -f tst.awk file
20160420084:0
20160420085:26
20160420090:5
$ awk -v type='unq' -f tst.awk file
20160420084:0
20160420085:19
20160420090:5
답변2
$ cat summarise.pl
#!/usr/bin/perl
use strict;
use List::Util qw(sum0); # useful function to sum elements of array
# handle command-line options
use Getopt::Long qw(VersionMessage :config gnu_getopt);
use Pod::Usage;
$main::VERSION='0.0-alpha';
my $help = 0;
my $type;
GetOptions('total|sum|s|t' => sub { $type .= 't' },
'unique|u' => sub { $type .= 'u' },
'both|b' => sub { $type = 'tu' },
'help|h|?' => \$help,
'version|V' => sub { VersionMessage() },
) or pod2usage(2);
pod2usage(-exitval => 0, -verbose => 2) if $help or (! @ARGV && -t);
$type = 'b' if length($type) > 1;
$type = 'u' if length($type) == 0; # default is unique
# Hash-of-Hashes (HoH) to hold timestamps, ids, and id counts.
# Primary key will be timestamp, secondary keys are the IDs,
# and values are the counts of each secondary key.
my %timestamps;
# read and process input file
while(<<>>) {
next if ($. == 1); # skip first line of input file(s)
chomp;
# remove square brackets and spaces from input line
s/[][]|\s+//g;
# split current line on colon and commas
my($ts,@ids) = split /[:,]/;
$ts = substr($ts,0,11);
$timestamps{$ts} = () unless (defined $timestamps{$ts});
# remove non-numeric elements of @ids array
@ids = grep { /^\d+$/ } @ids;
# Convert to the HoH structure.
map { $timestamps{$ts}{$_}++ } @ids;
close(ARGV) if eof; # reset line counter $. at end of each input file
}
# all input has been processed, so print the results.
foreach my $ts (sort keys %timestamps) {
my $u = scalar keys %{ $timestamps{$ts} };
my $s = sum0 values %{ $timestamps{$ts} };
if ($type eq 'u') {
printf "%s: %i\n", $ts, $u;
} elsif ($type eq 't') {
printf "%s: %i\n", $ts, $s;
} elsif ($type eq 'b') {
printf "%s: %i, %i\n", $ts, $u, $s;
};
}
__END__
=head1 summarise.pl
Script for counting and summarising Numbers & Unique numbers in each line.
=head1 SYNOPSIS
summarise.pl [options] [file ...]
=head1 OPTIONS
=over
=item B<--total>
print total number of IDs per timestamp
=item B<--unique>
print number of unique IDs per timestamp
=item B<--both>
print both unique and total number of IDs
=item B<--version>
Print script's version and exit
=item B<--help>
Print this help message and exit
=back
=cut
노트:목록::유틸리티,포드::사용법, 그리고Getopt::긴둘 다 핵심 Perl 모듈이며 Perl에 포함되어 있습니다.
perldoc pod
Perl의 "Plain Old Documentation" 내장 코드 문서가 작동하는 방식에 대한 자세한 내용은 참고자료를 참조하세요. 나는 단지 그 기능의 표면만 긁었을 뿐입니다.
예제 출력:
$ ./summarise.pl input.txt
20160420084: 0
20160420085: 19
20160420090: 5
$ ./summarise.pl input.txt -t
20160420084: 0
20160420085: 26
20160420090: 5
$ ./summarise.pl input.txt -b
20160420084: 0, 0
20160420085: 19, 26
20160420090: 5, 5
$ ./summarise.pl --version
./summarise.pl version 0.0-alpha
(Getopt::Long::GetOptions version 2.51; Perl version 5.32.1)
$ ./summarise.pl --help
summarise.pl
Script for counting and summarising Numbers & Unique numbers in each
line.
SYNOPSIS
summarise.pl [options] [file ...]
OPTIONS
--total, --sum, -t, -s
print total number of IDs per timestamp
--unique, -u
print number of unique IDs per timestamp
--both, -b
print both unique and total number of IDs
--version, -V
Print script's version and exit
--help, -h, -?
Print this help message and exit
getopt_long()
그건 그렇고, C 프로그램에서 사용되는 많은 GNU 함수와 마찬가지로 Perl Getopt::Long
모듈은 옵션 약어를 이해합니다. 예를 들어 --uni
, --uniq
, 등은 또는 와 동일하게 처리됩니다 -un
. 약어가 옵션 이름과 명확하게 일치할 만큼 길면 작동합니다.-u
--unique
%timestamps
그리고 해시 데이터 구조가 "어떻게 생겼는지" 알고 싶다면 :
{
"20160420084" => undef,
"20160420085" => {
105618372 => 1, 111295547 => 1, 111344871 => 1, 111352520 => 1, 111379566 => 1,
111394583 => 1, 111412662 => 1, 111413225 => 2, 111413281 => 2, 111413356 => 1,
111413432 => 2, 111413557 => 1, 111557948 => 2, 111557953 => 1, 111633904 => 2,
111646835 => 1, 111783178 => 1, 111783198 => 2, 111792767 => 2,
},
"20160420090" => {
111295547 => 1, 111344871 => 1, 111352520 => 1, 111379566 => 1, 111394583 => 1
},
}
해시의 해시는 각 요소가 해시일 수도 있는 연관 배열("해시")입니다.
perldoc perldsc
Perl 데이터 구조에 대한 자세한 내용은 참고자료를 참조하세요.