Easily handle CLI operation via Python instead of regular Bash programs
github.com
github.com
[1]: https://robm.me.uk/2013/11/ruby-enp/
-n causes Perl to assume the following loop around your program, which makes it iterate over filename arguments somewhat like sed -n or awk:
LINE:
while (<>) {
... # your program goes here
}
-p causes Perl to assume the following loop around your program, which makes it iterate over filename arguments somewhat like sed: LINE:
while (<>) {
... # your program goes here
} continue {
print or die "-p destination: $!\n";
}
https://linux.die.net/man/1/perlrunhttps://github.com/learnbyexample/Command-line-text-processi...
Which I've been using as my daily driver for a few years, and absolutely swear by it.
"an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code"
Whatever that means. They seem to do very different things as far as I can tell.
I especially like iterating over files as Path objects with the simple syntax
for f in p`.\*\.jpg`:
if f.isdir():
foo = $(echo @(f.absolute()))[I'm usually a fan of informative command names, but surely there's a happy medium]
Didn't know about it, thanks for this.
Oh, and small gotcha, if you want to try it, its:
pip3 install pypyp
rather than the obvious which installs something else entirely.One concern that I have is that it could be so useful that now your script is filled with `| pz`, and is launching Python processes at every line . Now you have a tangled hybrid of Bash and Python.
That said, it would be amazing if `pz` could take in some input arguments and output the Unixy equivalent if it can find one.
Thinking long term is a skill that is often realized only after one fails to make a previous long-term investment.
I think this is a gross misrepresentation of both technologies, to the point that it goes well beyond a normal apples-to-oranges comparison.
A shell script runs well on any standard-compliant implementation, just like python3.4 scripts will run exactly like they always did when running on a python3.4 interpreter.
Python's libraries break when asshats "deprecate naming conventions" only when you somehow assume that, say, your python3.10 script would run on python2.7, or just like your shell script breaks when the program it calls happens to break it's cli.
Also, is versioning still a problem given the pervasiveness of package managers with support for version pinning?
That's all fine and dandy until your shell script grows beyond a dozen lines of code or so. The moment that happens, shell scripts become barely readable and terribly hard to maintain, unlike alternatives such as python.
If you use functions to aid in abstraction, you can easily convert the function to a program in a more capable language as soon as it becomes too complicated.
In the end, I usually find that most of the things people replace good old unix tools with are better in one limited area, but miss a large part of what make the originals magic. Usually this is some combination of universal, discoverable, reduced dependencies, composable abstractions.
My bash-modules[0] project[1] may help you with that. Typically, I perform script refactoring in these steps:
1. Split code into few subroutines with clear boundaries between them, or split a large script into multiple simpler scripts.
2. Add an error handler with transparent message to every line of code.
3. Add command line options to override hard-coded things, to be able to test things in isolation.
4. Write documentation (man-page) for script, for future self.
5. Write test cases.
6. Refactor code, following best practices.
And that’s how you end up with bash scripts wrapped inside Docker images, that I have been seeing for the last couple of years.
$ echo -e "example\nwikipedia" | pz 's += ".com"'
$ echo -e "example\nwikipedia" | perl -lpe '$_.=".com"'
$ echo "hello world" | pz s[6:]
$ echo "hello world" | perl -pe '$_=substr($_,6)'
$ echo "hello world" | perl -pe 'substr($_,0,6)=""'
$ echo "hello world" | perl -lape '$_=$F[1]'
$ tail -f /var/log/syslog | pz -f '{len(s)}: {s}'
$ tail -f /var/log/syslog | perl -lpe '$_=length($_).": $_"'
$ echo "HELLO" | pz s.lower
$ echo "HELLO" | perl -pe '$_=lc'
$ echo "hello,5" | pz 's.split(",")[1]' | pz n+7
$ echo "hello,5" | perl -F, -lpe '$_=$F[1]+7'
$ pz --findall "(https?://[^\s]+)" < file.log
$ perl -lne 'print $1 if m{(https?://\S+)}' foo2.log
$ echo -e "1\n2\n3\n4" | pz --end sum
$ echo -e "1\n2\n3\n4" | perl -lne 'END{print $t} $t+=$_'
$ echo -e "1\n2\n2\n1\n3" | pz --end "sorted(set(lines))"
$ echo -e "1\n2\n2\n1\n3" | perl -ne 'END{print sort keys %h} $h{$_}++'
$ echo -e "red green\nblue red green" | pz 'C.update(s.split())' --end C.most_common
$ echo -e "red green\nblue red green" | perl -lae 'END{print "$_, $h{$_}" for sort keys %h} $h{$_}++ for @F'The behaviour of auto-imports https://github.com/CZ-NIC/pz#auto-import seems bit scary:
> Caveat: When accessed first time, the auto-import makes the row reprocessed. It may influence your global variables. Use verbose output to see if something has been auto-imported.
It sounds like this could cause some very subtle bugs. Maybe a strong and clear warning when a line is being reprocessed would help.
So many times I accidently fill up my scroll buffer with an unintended awk or grep mistake.
Maybe it’s not the ‘right’ way to get things done, but it’s quick and it works.
A super simple version for JS
It could be even more useful with an `f` variable that holds the ‘words’ obtained from splitting `s` at whitespace.
It was so much easier in CMD.exe
mv * *.com