Using Raku (formerly known as Perl_6)
#recover all key/value pairs:
~$ cat file | raku -e 'my @a = lines>>.split(";", :skip-empty)>>.[1..*].flat; \
my %hash; for @a>>.split("=") {%hash.=append: $_}; \
.say for %hash.sort;'
#recover values for specific key:
~$ cat file | raku -e 'my @a = lines>>.split(";", :skip-empty)>>.[1..*].flat; \
my %hash; for @a>>.split("=") {%hash.=append: $_}; \
say %hash<creq_recv>;'
Above is an answer coded in Raku, a Perl-family programming language. The question practically begs for a key-value solution, and Raku doesn't disappoint.
For the above two code examples, they are identical except for the last statement. Briefly, lines
of the file are read in, which has the effect of chomping off trailing \n
newlines by default. Then this input is split on ;
semicolons to produce element that are [1..*]
indexed to remove the first (time/date) element, flat
tened, and stored in the @a
array. Then the elements of @a
are are >>
individually split on =
equal-sign. These resulting elements are append
ed en mass to the %hash
. Raku when given input in this manner makes a key/value pair out of every successive two elements.
In the first code example, all keys/value pairs are returned. In the second code example, only the values associated with the creq_recv
key are returned.
Sample Input:
2022-10-21 16:00:08;areq_in=0;areq_qavg=0;areq_qmax=0;areq_sent=0;ares_out=0;ares_out_err=0;ares_out_ok=0;ares_qavg=0;ares_qmax=0;ares_recv=0;ares_tavg=0;ares_tmax=0;creq_out=0;creq_qavg=0;creq_qmax=0;creq_recv=0;cres_in=0;cres_qavg=0;cres_qmax=0;cres_sent=0;lic_rej=0;lic_use=0;mbr_from=0;mbr_to=0;mreject=0;mreject_conn=0;msys_recv=0;msys_sent=0;
Sample Output for first code example (second code example returns 0
):
areq_in => 0
areq_qavg => 0
areq_qmax => 0
areq_sent => 0
ares_out => 0
ares_out_err => 0
ares_out_ok => 0
ares_qavg => 0
ares_qmax => 0
ares_recv => 0
ares_tavg => 0
ares_tmax => 0
creq_out => 0
creq_qavg => 0
creq_qmax => 0
creq_recv => 0
cres_in => 0
cres_qavg => 0
cres_qmax => 0
cres_sent => 0
lic_rej => 0
lic_use => 0
mbr_from => 0
mbr_to => 0
mreject => 0
mreject_conn => 0
msys_recv => 0
msys_sent => 0
For a more informative return, use Raku's =>
pair-constructor, changing the last statement to:
$_ = "creq_recv" andthen say $_ => %hash{$_};
...which returns:
creq_recv => 0
Finally, Raku implements react
blocks, which can designed to receive a Supply
(lets say, for example, $*IN.lines
lines-received-via-StdIN), and whenever
received, run code. Like so:
~$ tail -f test.log | raku -e 'react {whenever Supply( $*IN.lines ) { \
my @a = $_.map( *.split(";", :skip-empty).[1..*] ).flat; \
my %hash; for @a.map: *.split("=") { %hash.=append: $_ }; \
$_ = "creq_recv" andthen say $_ => %hash{$_} // Nil; } };'
creq_recv => 0
creq_recv => 0
^C
https://docs.raku.org/language/concurrency#react
https://docs.raku.org/language/hashmap
https://docs.raku.org/routine/=%3E
https://raku.org
PS: There's an absolutely stellar chapter on "Associatives" (i.e. Hashes and Maps) in brian d foy's book Learning Perl6.
12
,34
etc.), you also wantcreq_recv=
, is that not correct?