q
q copied to clipboard
Add a fixed width input mode
Maybe consider adding an option to parse pretty printed input, to complement -b
for pretty printed output.
I use q
on kubectl
output, but when one of the values has a space in it, it breaks the parsing:
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
cms-api cms.internal 10.215.0.40 80, 443 20d
content-portal content.internal 10.215.0.40 80, 443 20d
Usually q -HOb 'select * from -'
is a no-op, but in this case:
$ kubectl get ingress | q -HOb 'select * from -'
NAME HOSTS ADDRESS PORTS AGE c6
cms-api cms.internal 10.215.0.40 80, 443 20d
content-portal content.internal 10.215.0.40 80, 443 20d
The b
option is included for convenience but in fact violates Unix philosophy. You can get a similar result by piping q
output through column -t
, so it's not strictly needed. Therefore I think adding another option on the input side would be a step in the wrong direction. Instead I suggest making an input transformation to distinguish between column separators and literal spaces:
kubectl get ingress | sed 's/ \+/\t/g' | q -tHOb 'select * from -'
Or instead of -b
use the suggested column
command:
kubectl get ingress | sed 's/ \+/\t/g' | q -tHO 'select * from -' | column -t -s$'\t'
This also leads to a slightly different spacing (which might be preferable).
While I understand the issue with kubectl's output, I agree with @bitti on this. Adding such a capability to q would be cumbersome, probably error prone, and a step in the wrong direction. kubectl effectively has a bug in its output, since it does provide multiple output formats, but doesn't fully provide a table format that is machine-parsable.
I would take another approach and create a more generic preprocessing capability that converts the visual table structure to a more logical one.
Here's a short script I've written to convert visual-space-delimited fields into logical ones. It uses the header row as a hint on how to split the other rows. You can use it as follows (notice that i've added the -d ,
since i've made the csv-size script hardcoded to create comma separated fields).
kubectl get ingress | ./csv-ize | q -HOb -d , 'select * from -'
Below is the code for csv-ize
. Obviously it could benefit from parameterizing some stuff and making it more robust to errors.
#!/usr/bin/env python
import os,sys
import re
import csv
w = csv.writer(sys.stdout,delimiter=',',quotechar='"',quoting=csv.QUOTE_ALL)
h = sys.stdin.readline()[:-1]
positions = [0] + [x.start()+1 for x in re.finditer(' [^ ]',h)] + [len(h)]
def split_line(l,positions,trim=True):
do_format = lambda v: v.strip() if trim else v
return [do_format(l[p0:p1]) for p0,p1 in zip(positions,positions[1:])]
header = split_line(h,positions)
w.writerow(header)
line = sys.stdin.readline()
while line:
line = line[:-1]
w.writerow(split_line(line,positions))
line = sys.stdin.readline()