MCPcopy Create free account
hub / github.com/wireservice/csvkit / CSVStack

Class CSVStack

csvkit/utilities/csvstack.py:23–145  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

21
22
23class CSVStack(CSVKitUtility):
24 description = 'Stack up the rows from multiple CSV files, optionally adding a grouping value.'
25 # Override 'f' because the utility accepts multiple files.
26 override_flags = ['f', 'L', 'I']
27
28 def add_arguments(self):
29 self.argparser.add_argument(
30 metavar='FILE', nargs='*', dest='input_paths', default=['-'],
31 help='The CSV file(s) to operate on. If omitted, will accept input as piped data via STDIN.')
32 self.argparser.add_argument(
33 '-g', '--groups', dest='groups',
34 help='A comma-separated list of values to add as "grouping factors", one per CSV being stacked. These are '
35 'added to the output as a new column. You may specify a name for the new column using the -n flag.')
36 self.argparser.add_argument(
37 '-n', '--group-name', dest='group_name',
38 help='A name for the grouping column, e.g. "year". Only used when also specifying -g.')
39 self.argparser.add_argument(
40 '--filenames', dest='group_by_filenames', action='store_true',
41 help='Use the filename of each input file as its grouping value. When specified, -g will be ignored.')
42
43 def main(self):
44 if isatty(sys.stdin) and self.args.input_paths == ['-']:
45 sys.stderr.write('No input file or piped data provided. Waiting for standard input:\n')
46
47 has_groups = self.args.groups is not None or self.args.group_by_filenames
48
49 if self.args.groups is not None and not self.args.group_by_filenames:
50 groups = self.args.groups.split(',')
51
52 if len(groups) != len(self.args.input_paths):
53 self.argparser.error(
54 'The number of grouping values must be equal to the number of CSV files being stacked.')
55 else:
56 groups = None
57
58 group_name = self.args.group_name if self.args.group_name else 'group'
59 use_fieldnames = not self.args.no_header_row
60
61 if use_fieldnames:
62 Reader = agate.csv.DictReader
63 else:
64 Reader = agate.csv.reader
65
66 headers = []
67 stdin_fieldnames = []
68 stdin_first_row = []
69
70 for path in self.args.input_paths:
71 f = self._open_input_file(path)
72 file_is_stdin = path == '-'
73
74 _skip_lines(f, self.args)
75 rows = Reader(f, **self.reader_kwargs)
76
77 if use_fieldnames:
78 if rows.fieldnames:
79 for field in rows.fieldnames:
80 if field not in headers:

Callers 1

launch_new_instanceFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected