Created by Drew Gulino as a recipe on ActiveState, the recipe has now been ported to 577075_Pyliner__Script_run_arbitrary_Pythcode. This project aims to make the recipe more accessible.
A Python script that runs arbitrary Python scripts in an input loop. This allows one-liner Python scripts similarly to how Perl runs them (-l,-a,-n,-F, BEGIN, END)
It provides additional syntax that allows multiline Python scripts to be run on a single line
I work on *nix systems and use one-liner bash+awk+sed+etc.. scripts all the time, but I find I need Perl for some features. But I prefer and remember Python better. There are a few other scripts that allow something like Perl's cool one-liner '-lane', 'BEGIN' ,'END', etc, but don't have the full functionality.
This script is based on http://code.activestate.com/recipes/437932-pyline-a-grep-like-sed-like-command-line-tool/ (Graham Fawcett + Jacob Oscarson, Mark Eichin) and Perl. It attempts to provide all the one-liner functionality that Perl provides. G.F., J.O., and M.E.'s original recipe is now hosted at 437932_Pyline_greplike_sedlike_commandline
To get this to work, I had to create some additional syntax to allow Python to run on a single line without tabs. I understand this goes against much of what Python 'stands' for, but I'm pragmatic. This is no PEP to modify the language or a critique of Python's syntax; I just like the language and want to use it in an area that it's not well adapted for.
pyliner (options) "script"
- options
-a
enables auto-split of input into theF[]
array.-F
specifies the characters to split on with the-a
option (default=" ").-p
loops over and prints input.-n
loops over and does not print input.-l
strips newlines on input, and adds them on output.-M
lets you specify module imports.-o
print out parsed and indented script on multiple lines.-e
(assumed - does nothing, added for Perl compatibility).
- script
";"
specify newlines":"
will start an indent for the following lines"?;"
will add a newline and dedent the following lines"/;"
will reset the indent the far left"BEGIN:"
starts the an initial script not run in the input loop"END:"
starts part of the script run after the input loop"#/"
ends both the"BEGIN:"
and"END:"
portions of the script
- variables
F[]
= split inputline
= current input lineNR
= current input line number
- functions
I(x)
= function returnsF[x]
cast to integerf(x)
= function returnsF[x]
cast to float
test.txt:
10,test 1,rest 100,test 10,best 1000,we 1,see
Example 1:
Return the sum of numbers in the first column that are greater than 90:
cat test.txt | ./pyline.py -F"," -lane \ 'BEGIN:sum=0#/if i(0) > 90:sum+=i(0)) END:print sum#/'output:
1100
Example 2:
pyliner
cat test.txt | ./pyliner.py -F"," -lane \ 'BEGIN:sum=0#/a=f(0);if a > 90:sum+=a END:print sum/NR#/'output:
183.333333333
perl:
cat test.txt | perl -F"," -lane \ 'BEGIN {$sum=0; } ;$sum=$sum+=@F[0] if @F[0]>90;END { print $sum/$.; }'output:
183.333333333333
Example 3:
Chunk average (average of every N amount of numbers in a pipe):
echo -en "1\n 2\n 3\n 4\n 10\n 10\n 10\n 10\n" | ./pyliner.py -lane -F"," \ 'BEGIN:s=0;n=4#/s+=f(0);if not NR % n:print s/n;s=0'output:
2.5 10.0
This program is licensed under the GNU V3 license. See LICENSE.md for the full text.