SEL is a technology demonstrator and kind of sketch-program, created for Common Output Format project. If you want something production-ready - check Miller.
As root:
# pkg_add python36 # pkg_add py36-pip # pkg_add py36-six
As user:
$ pip3.6 install --user parsimonious $ pip3.6 install --user termcolor
As root:
# apt-get install python3 python3-six python3-pip python3-termcolor
As user:
$ pip3 install parsimonius
Then change shebang in sel
to #!/usr/bin/python3 -tt
In general, sel
invocation uses three kinds of parameters:
flags, selectors, filters.
Currently sel
supports two different option sets as well as two
different filter grammars.
$ sel -h Usage(1): sel [-qh] [<column>, [<column>, ...]] [where <filter>] Usage(2): sel [-qh] -f [<column>, [<column>, ...]] [-w <filter>] ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ flag column selector filter
There are two forms of parameters - "dashless ones" are probably more suitable for passing arguments when filter is called from another app and parameters are passed via additional option, for example:
df --of '1,2,Used'
Version1 | Version2 | Role |
-q |
-q |
Don't print meta-data or headers |
-f <column> |
<column> |
Selects columns to print |
-w <filter> |
where <filter> |
Conditionals for rows |
Example:
$ df | sel 1,2,Used,Used where Used -eq 0 # meta prog:df # Filesystem 1024-blocks Used Used udev 1837416 0 0 tmpfs 1857800 0 0
There also two filter grammars. Unfortunately, in shell environment
convenient operators like <
, >
, >=
, (
or )
are
cumbersome in use and may cause subtle bugs.
There are some rules:
- column names are always case-insensitive
- literals are not quoted. That makes impossible to write someone
like comparison between two columns
when Used -gt Free
but is a lot easier when we need awhen Mounted -starts /opt
.
Version1 | Version2 | meaning |
-a or , |
and or , |
AND |
-o |
or |
OR |
-eq |
eq |
equals |
-gt |
gt |
greater than |
-lt |
lr |
less than |
-le |
le |
less or equal than |
-gt |
gt |
greater or equal than |
-starts |
starts |
starts with |
-ends |
ends |
ends with |
-has |
has |
contains |
[ and ] |
[ and ] |
brackets for grouping statements |
NOT |
NOT |
negation (XXX: not well tested) |
Some examples:
$ cat samples/df.txt | ./sel 1,2,3 where Used -gt 0 -a Filesystem -eq tmpfs # meta prog:df # Filesystem 1024-blocks Used tmpfs 371560 5956 tmpfs 1857800 56916 tmpfs 5120 4 tmpfs 371560 36 $ cat samples/df.txt | ./sel 1,2,3 where Used -gt 0, Filesystem -eq tmpfs # meta prog:df # Filesystem 1024-blocks Used tmpfs 371560 5956 tmpfs 1857800 56916 tmpfs 5120 4 tmpfs 371560 36
"Dashless" filter grammar:
$ export SEL_GRAMMAR=2 $ cat samples/df.txt | ./sel 1,2,3 where Used gt 0 and Filesystem eq tmpfs # meta prog:df # Filesystem 1024-blocks Used tmpfs 371560 5956 tmpfs 1857800 56916 tmpfs 5120 4 tmpfs 371560 36 $ cat samples/df.txt | ./sel 1,2,3 where Used gt 0, Filesystem eq tmpfs # meta prog:df # Filesystem 1024-blocks Used tmpfs 371560 5956 tmpfs 1857800 56916 tmpfs 5120 4 tmpfs 371560 36
Case-insensitibility for columns and case-sensitible literals:
# cat samples/df.txt | ./sel 1,2,3 where used gt 0 and filesystem eq Tmpfs # meta prog:df # Filesystem 1024-blocks Used $ cat samples/df.txt | ./sel 1,2,3 where used gt 0 and filesystem eq tmpfs # meta prog:df # Filesystem 1024-blocks Used tmpfs 371560 5956 tmpfs 1857800 56916 tmpfs 5120 4 tmpfs 371560 36 $ cat samples/df.txt | ./sel 1,2,3 where used gt 0 and filesystem eq TMPFS # meta prog:df # Filesystem 1024-blocks Used $ cat samples/df.txt | ./sel 1,2,3 where used gt 0,filesystem eq tmpfs # meta prog:df # Filesystem 1024-blocks Used tmpfs 371560 5956 tmpfs 1857800 56916 tmpfs 5120 4 tmpfs 371560 36
More complicated example
$ cat sample/df.txt | ./sel -f 1,2,Used,Used,Mounted -w Used -gt 0 -a Mounted -starts /rr # meta prog:df # Filesystem 1024-blocks Used Used Mounted /dev/sdx2 123723748 10807024 10807024 /rr/rrr 1.2.3.4:/foobar2/test1 956688640 740075264 740075264 /rr/test1 1.2.3.4:/foobar2/test2 956688640 740075264 740075264 /rr/test2 1.2.3.4:/foobar2/test9 956688640 740075264 740075264 /rr/test9
Tabular data can be converted to other format with standard utilities and only few lines of code. For more examples take a look at xml directory.