---
" The shell file management features. This includes redirection and pipelines. This is trickier. Much of this can be done with subprocess. But some things that are easy in the shell are unpleasant in Python. Specifically stuff like (a
b; c ) | something >result. This runs two processes in parallel (with output of a as input to b), followed by a third process. The output from that sequence is run in parallel with something and the output is collected into a file named result. That's just complex to express in any other language. |
---
" In UNIX, you’d have something like:
for f in *; do echo "Processing $f file..."; done
While in PowerShell?, you’d go with something similar to:
Get-ChildItem? "."
An equivalent functionality in Python can be achieved with:
from os import listdir
for f in listdir('.'): print('Processing {} file...'.format(f)) "
" $> cat names.txt
namecount.py. And PowerShell? folks: $> Get-Content names.txt | python namecount.py. | ||
namecount.py | sort -rn. And if you’re using PowerShell?: $> Get-Content names.txt | python namecount.py | Sort-Object { [int]$_.split()[-1] } -Descending |
python namecount.py and $> Get-Content names.txt | python namecount.py | sort { [int]$_.split()[-1] } -Descending |
"First off, the provided Unix commands _don't work_ (should have used `sort -rn -k 2`), while the provided powershell, as verbose as it is, does work."
" the entire python script along with the wrapping unix commands is encapsulated with a powershell 1-liner:
cat ./names.txt | group | sort -d Count"
---
Ultimatt 1 day ago [-]
Skip awk, use perl....
The alias below sets perl to loop over STDIN splitting each line on more than one whitespace character and populate an array F. The -nE will then Evaluate an expression from the command line looping over the input line-by-line.
alias glorp='perl -aF"/\s+/" -nE'
So now we have the command `glorp` to play with which has more familiar syntax than awk and all of CPAN available to play with!
$ [data is generated] | glorp '/Something/ and say $F[2]'
We have access to any Perl module by putting -MModule::Name=function after the command, the following will parse a JSON record per line and glorp out what we wanted:
$ echo -e '{"hello":"world"}\n{"hello":"cat"}' | glorp 'say decode_json($_)->{hello};' -MJSON=decode_json world cat
Maybe you are used to using curl too. There is a nice web framework in Perl called Mojolicious (http://mojolicious.org) that provides a convenience module called 'ojo' for command line use. So grabbing the summary sentence from Wikipedia articles is as straight forward as below. Notice Mojolicious lets us use CSS selectors!
$ echo -e 'grep\nawk\nperl' \ | glorp 'say g("wikipedia.org/wiki/$F[0]")->dom->at("#mw-content-text > div > p")->all_text' -Mojo
reply
vidarh 1 day ago [-]
Here's the equivalent for Ruby:
alias glorp='ruby -ane '
$ [data is generated] | glorp ' ~ /Something/ and puts $F[2]'
Or:
$ echo -e '{"hello":"world"}\n{"hello":"cat"}' | glorp 'puts JSON.load($_)["hello"] ' -rjson
(Of course Ruby got the -a autosplit-mode and the -n assumed 'while gets(); ... end' loop from Perl along with $_ and $F, so it's very intentional that they're similar)
reply
kolodny 1 day ago [-]
Somewhat related nodejs self plug: Use nip https://github.com/kolodny/nip
$ echo -e 'this\nis\na\nwhatever foo' | nip 'return /whatever/.test(line) && cols[1]' # foo
reply
Ultimatt 1 day ago [-]
Awesome thanks for sharing this! I was too lazy to give a Ruby example alongside.
reply
jedisct1 1 day ago [-]
And Ruby regexes are amazing.
reply
omaranto 1 day ago [-]
I thought that they were amazing because they were just like Perl's. Are there any differences?
reply
---
great article about some neat things in bash that we can probably learn from:
https://zwischenzugs.com/2018/01/06/ten-things-i-wish-id-known-about-bash/
---
jordigh 8 hours ago [-]
Using readline is a great thing to know about too.
My favourite little-known readline command is operate-and-get-next:
https://www.gnu.org/software/bash/manual/html_node/Miscellan...
You can use it to search back in history with C-r and then execute that command with C-o and keep pressing C-o to execute the commands that followed that one in history. Very helpful for executing a whole block of history.
For some reason, this documentation is hard to find! It's not here, for example:
http://readline.kablamo.org/emacs.html
I'm a bit saddened when readline replacements don't implement C-o. For example, the Python REPLs don't have it.
reply
lillesvin 6 hours ago [-]
I've overridden ctrl-r in my local Bash to search with fzf[0] and I'm using my history so much more now.
Didn't know about ctrl-o though, it sounds great! I hope that my ctrl-r override doesn't somehow break it.
[0]: https://github.com/junegunn/fzf
E: Fixed link.
reply
CaptSpify? 5 hours ago [-]
That link is a 404 for me?
reply
tokenizerrr 5 hours ago [-]
It had a trailing >, https://github.com/junegunn/fzf
reply
---
chriswarbo 54 minutes ago [-]
For me, the biggest gotcha in bash is whether or not a sub-process/shell will be invoked, which can affect things like mutable variables and the number of open file handles. For example:
COUNT=0 someCommand | while read -r LINE do COUNT=$(( COUNT + 1 )) done echo "$COUNT"
This will always print `0`, since the `COUNT=` line will be run in a sub-process due to the pipe, and hence it can't mutate the outer-process's `COUNT` variable. The following will count as expected, since the `<()` causes `someCommand` to run in a sub-process instead:
COUNT=0 while read -r LINE do COUNT=$(( COUNT + 1 )) done < <(someCommand) echo "$COUNT"
Another issue I ran into is `$()` exit codes being ignored when spliced into strings. For example, if `someCommand` errors-out then so will this:
set -e FOO=$(someCommand) BAR="pre $FOO post"
Yet this will fail silently:
set -e BAR="pre $(someCommand) post"
reply
---
bash:
parameter result ----------- ------------------------------ $name polish.ostrich.racing.champion ${name#*.} ostrich.racing.champion ${name##*.} champion ${name%%.*} polish ${name%.*} polish.ostrich.racing ${name%.*.*} polish.ostrich ${name#*.*.} racing.champion [1]