Structure of this website¶
Tutorial¶
Introduction¶
One should use the right tool for the right task. But Learning 300 tools is counterproductive, so one needs a fallback. To be generic enough that fallback must be scriptable. So we have AWK, Perl, Sed, TCL... and their read-only languages.
Enters py1, it aims at being a “Python AWK”.
Indents and dedents can be replaced with {{
and }}
, line feeds can be replaced with ;
. An optional for loop iterates on input lines.
Usage¶
Using {{
}}
instead of indentation, and ;
to separate statements:
py1 "a = 1+2; if a > 4: {{ print(a) }}"
The wrapper script defines a convenient set of 1&2-letters variables and functions.
It can also include a for loop that iterates on input lines. To get the for loop, pass --each-line
/-l
.
For example, to count lines matching '$a*^'
:
py1 --begin "count=0" --each-line "if M('$a*^'): count += 1"
--end "P(count)"
Lastly the wrapper script provide a short notation to easily import modules.
py1 --import "math/*" "P(cos(pi))"
To learn more you can read the list of one letter functions and variables or just look at examples and figure out the rest.
Sustainable hacking¶
If you find yourself writing a longer than readable one-liner, you can
transform it in regular Python code, easily refactored for later reuse.
Just add --code=full
.
More!¶
Interested? You can install with:
pip install py1cmd
To learn more you can read the list of one letter functions and variables or just look at examples and figure out the rest.
How to contribute?¶
I wrote some advices and documented the internals here. Feel free to just contact unbrice.
Examples¶
Unix timestamp¶
Formats a Unix timestamp (1443214640) as a human-readable string.
py1 -i 'time/ctime' 'P(ctime(1443214640))'
To do so we import ctime from the time module and print it.
Count blank lines¶
Count the number of blank lines in a file.
py1 -b 'c=0' -l 'if not L: c += 1' -e 'P(c)'
Here we define an acumulator variable and increment it when the line satisfies a criteria.
Print 2nd and 3rd fields¶
Show the second and third fields of /etc/passwd
, a file whose fields are separated by “:
”.
cat /etc/passwd | py1 -b 'WS=":"' -l 'P(W[1:2])'
Here we override WS to use the “:
” separator of /etc/passwd
.
Show lines matching a regexp¶
Show lines matching the regexp ‘$a+^’.
py1 -l 'if M("$a+^", L): P(L)'
Here we use the M matching function to match the regexp.
Count blank lines again¶
Count the number of blank lines in a file.
py1 -e 'P(sum(1 if l else 0 for l in F))'
Here we do not set a per-line statement and instead have sum iterate over F.
Group by¶
Given a file of ‘$name $value’, with name being repeated, sum the values for each name.
py1 -b 'd=defaultdict(int)' -l 'd[W[0]] += int(W[1])'
-e 'for n, v in d: P(n, v)'
Convenience variables¶
Follows a list of the builtin functions and variables.
Per-line¶
Name | Description | Type |
---|---|---|
L | The current line, stripped | str |
R | The raw current line | str |
LN | The current line number | int |
W | Words of R split on WS or WRE | str |
NW | Length of W | int |
Global¶
These are defined in the whole program.
Name | Usage | Default | Type |
---|---|---|---|
ENV | Maps names to values of environment variables | os.environ |
{str : str } |
Input¶
Name | Usage | Default | Type |
---|---|---|---|
F | The input file | sys.stdin |
file (io.FileIO ) |
WS | Word separator, ignored if WRE is set | Any whitespace | str |
WRE | Word RegExp separator | None |
str or re |
Output¶
Name | Usage | Default | Type |
---|---|---|---|
OF | The output file | sys.stdout |
file (io.FileIO ) |
OWS | Output Word Separator | space | str |
OLS | Output Line Separator | \n | str |
Functions¶
-
M
(pattern, string=None, flags=0)[source]¶ Returns all capture groups starting with the full match.
Parameters: - pattern (str) – The regexp to match on.
- string (str) – The string that will be matched, default to the full line (the R variable).
- flags (int) – Matching option as per
re.match()
Returns: Capture groups, starting with the full match; or None if there were no match.
Return type: tuple(str) or None
Imports¶
--i
/--import
is a shortcut to easily import external libraries.
Importing a module¶
The equivalent of import xyz
is --import xyz
.
It is equivalent to --begin import xyz
, just shorter.
You can use -i xyz
which is even shorter.
py1 --begin 'import math' 'P(math.cos(math.pi))'
py1 --import 'math' 'P(math.cos(math.pi))'
py1 -i 'math' 'P(math.cos(math.pi))'
Importing specific symbols¶
The equivalent of from xyz import abc
is --import xyz/abc
.
You can import multiple functions with --import xyz/abc,def
.
Something like -i xyz/*
is equivalent to from xyz import *
.
py1 --import 'math/cos,pi' 'P(cos(pi))'
py1 -i 'math/*' 'P(cos(pi))'
Importing with a specific name¶
The equivalent of import abc as ABC
is --import abc:ABC
. You can rename specific symbols in the same way like --import xyz/abc:ABC
.
py1 --import 'math:M' 'P(M.cos(M.pi))'
Internals¶
This describes the implementation of py1, not its usage.
py1.curly |
Implements the un-escaping of the {{ }} indents. |
py1.runner |
Helps running user-provided code and getting readable backtraces. |
py1.template_reader |
The template with the conveniency variables. |
py1.tty |
Functions for making the most of a TTY. |