Structure of this website

Tutorial

Installation

To install from Pypi:

pip install py1cmd

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.

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

P(*args, **kwargs)[source]

Like print() but honors OWS, OLS & OF.

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

S(pattern, repl, string=None, count=0, flags=0)[source]

Substitutes pattern with repl in string (or R if string is None).

Parameters:
  • pattern (str) – The regexp to match on.
  • repl (str) – The string to substitute the matches with.
  • string (str) – The string that will be matched, default to the full line (the R variable).
  • count (int) – Replace at most that many occurences.
  • flags (int) – Matching option as per re.sub()
Returns:

The string after substitutions.

Return type:

str

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.

Indices and tables