line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::RecordStream::Operation::tocsv; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = "4.0.24"; |
4
|
|
|
|
|
|
|
|
5
|
2
|
|
|
2
|
|
813
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
53
|
|
6
|
|
|
|
|
|
|
|
7
|
2
|
|
|
2
|
|
10
|
use base qw(App::RecordStream::Operation); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
158
|
|
8
|
|
|
|
|
|
|
|
9
|
2
|
|
|
2
|
|
13
|
use App::RecordStream::Record; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
35
|
|
10
|
2
|
|
|
2
|
|
467
|
use Text::CSV; |
|
2
|
|
|
|
|
15949
|
|
|
2
|
|
|
|
|
908
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
sub init { |
13
|
5
|
|
|
5
|
0
|
14
|
my $this = shift; |
14
|
5
|
|
|
|
|
14
|
my $args = shift; |
15
|
|
|
|
|
|
|
|
16
|
5
|
|
|
|
|
10
|
my $header = 1; |
17
|
5
|
|
|
|
|
43
|
my $key_groups = App::RecordStream::KeyGroups->new(); |
18
|
5
|
|
|
|
|
12
|
my $delim = ','; |
19
|
|
|
|
|
|
|
my $spec = { |
20
|
3
|
|
|
3
|
|
2082
|
"key|k=s" => sub { $key_groups->add_groups($_[1]); }, |
21
|
1
|
|
|
1
|
|
1454
|
"noheader|nh" => sub { $header = 0 }, |
22
|
5
|
|
|
|
|
60
|
"delim|d=s" => \$delim, |
23
|
|
|
|
|
|
|
}; |
24
|
|
|
|
|
|
|
|
25
|
5
|
|
|
|
|
33
|
$this->parse_options($args, $spec); |
26
|
5
|
|
|
|
|
16
|
$this->{'KEY_GROUPS'} = $key_groups; |
27
|
|
|
|
|
|
|
|
28
|
5
|
50
|
|
|
|
21
|
die "Delimiter must be a single character\n\n" |
29
|
|
|
|
|
|
|
unless length $delim == 1; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# binary => 1 is to handle new lines in field values |
32
|
5
|
|
|
|
|
60
|
$this->{'CSV'} = Text::CSV->new({ |
33
|
|
|
|
|
|
|
binary => 1, |
34
|
|
|
|
|
|
|
sep_char => $delim, |
35
|
|
|
|
|
|
|
}); |
36
|
|
|
|
|
|
|
|
37
|
5
|
|
|
|
|
854
|
$this->{'FIRST'} = 1; |
38
|
5
|
|
|
|
|
72
|
$this->{'HEADERS'} = $header; |
39
|
|
|
|
|
|
|
}; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub accept_record { |
42
|
25
|
|
|
25
|
0
|
43
|
my $this = shift; |
43
|
25
|
|
|
|
|
37
|
my $record = shift; |
44
|
|
|
|
|
|
|
|
45
|
25
|
100
|
|
|
|
58
|
if ( $this->{'FIRST'} ) { |
46
|
5
|
|
|
|
|
18
|
$this->{'FIRST'} = 0; |
47
|
|
|
|
|
|
|
|
48
|
5
|
100
|
|
|
|
25
|
if ( $this->{'KEY_GROUPS'}->has_any_group() ) { |
49
|
3
|
|
|
|
|
14
|
$this->{'KEYS'} = $this->{'KEY_GROUPS'}->get_keyspecs($record); |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
else { |
52
|
2
|
|
|
|
|
24
|
$this->{'KEYS'} = [sort keys %$record]; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
5
|
100
|
|
|
|
23
|
if ( $this->{'HEADERS'} ) { |
56
|
4
|
|
|
|
|
14
|
$this->output_values($this->{'KEYS'}); |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
25
|
|
|
|
|
38
|
my @values; |
61
|
25
|
|
|
|
|
40
|
foreach my $key (@{$this->{'KEYS'}}) { |
|
25
|
|
|
|
|
63
|
|
62
|
45
|
|
|
|
|
69
|
push @values, ${$record->guess_key_from_spec($key)}; |
|
45
|
|
|
|
|
120
|
|
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
25
|
|
|
|
|
86
|
$this->output_values(\@values); |
66
|
|
|
|
|
|
|
|
67
|
25
|
|
|
|
|
139
|
return 1; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub output_values { |
71
|
29
|
|
|
29
|
0
|
48
|
my $this = shift; |
72
|
29
|
|
|
|
|
42
|
my $values = shift; |
73
|
|
|
|
|
|
|
|
74
|
29
|
|
|
|
|
59
|
my $csv = $this->{'CSV'}; |
75
|
29
|
|
|
|
|
95
|
$csv->combine(@$values); |
76
|
29
|
|
|
|
|
529
|
$this->push_line($csv->string()); |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub add_help_types { |
80
|
5
|
|
|
5
|
0
|
14
|
my $this = shift; |
81
|
5
|
|
|
|
|
31
|
$this->use_help_type('keyspecs'); |
82
|
5
|
|
|
|
|
23
|
$this->use_help_type('keygroups'); |
83
|
5
|
|
|
|
|
18
|
$this->use_help_type('keys'); |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub usage { |
87
|
0
|
|
|
0
|
0
|
|
my $this = shift; |
88
|
|
|
|
|
|
|
|
89
|
0
|
|
|
|
|
|
my $options = [ |
90
|
|
|
|
|
|
|
['noheader|--nh', 'Do not output headers on the first line'], |
91
|
|
|
|
|
|
|
['key|-k ', 'Comma separated keys to output. Defaults to all fields in first record. May be a keyspec, may be a keyspec group'], |
92
|
|
|
|
|
|
|
['delim|-d ', "Field delimiter to use when outputting lines (default ',')."], |
93
|
|
|
|
|
|
|
]; |
94
|
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
|
my $args_string = $this->options_string($options); |
96
|
|
|
|
|
|
|
|
97
|
0
|
|
|
|
|
|
return <
|
98
|
|
|
|
|
|
|
Usage: recs-tocsv [files] |
99
|
|
|
|
|
|
|
__FORMAT_TEXT__ |
100
|
|
|
|
|
|
|
This script outputs csv formatted recs. With the --delim option, it can |
101
|
|
|
|
|
|
|
output tsv or other line-based formats with character-separated fields. |
102
|
|
|
|
|
|
|
__FORMAT_TEXT__ |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
Arguments: |
105
|
|
|
|
|
|
|
$args_string |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
Examples |
108
|
|
|
|
|
|
|
# Print records to csv format with headers |
109
|
|
|
|
|
|
|
recs-tocsv myrecords |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# Only print time and a nested value of stat/avg |
112
|
|
|
|
|
|
|
... | recs-tocsv --key time,stat/avg |
113
|
|
|
|
|
|
|
USAGE |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
1; |