3 ms·
shell + shell tools + piping = a league of its own. As a big fan and advocate of a low level language (C) and a high level language (Python), as a combo, being
by fizixer 8y ago
shell + shell tools + piping = a league of its own.
As a big fan and advocate of a low level language (C) and a high level language (Python), as a combo, being a very powerful paradigm, I still can't believe some of the things the, shall we call it, shell piping workflow, let's you accomplish in one line and in a matter of minutes.
Here's what you do.
Say you have a text log file. It's "semi structured" (like most log files) in that you can extract quite a bit of information using things like grep/sed/awk, but still not fully parse it (without a very complex parser; we don't want to get into that). What's the first thing you do with the log file? You view it:
view logfile
(view is just opening the file in vim in read-only mode, if you don't have it, you can use "vim -R"). You inspect the file and then quit. Try this instead:
cat logfile | view -
(don't forget the hyphen at the end). Again, inspect and quit (e.g., using :q). You might say, what a round-about/inefficient way to view a logfile. But. Now you can do something in the middle:
cat logfile | do something | view -
inspect and quit. Or more than one thing
cat logfile | do something | do something else | view -
and you keep adding the piped commands until you're satisfied with your output. Once you're satisfied, you can dump the output into another text file as a "report" by replacing the last "| view -" with "> reportfile".
cat logfile | many | processing | commands | later > reportfile
and you can do this multiple times to generate multiple report files of various kinds. And you can concatente some of those report files
cat file1 file2
or put some columns of some of the report side by side
paste -sd' ' <(cat file1 | pick column) <(cat file2 | pick column)
The possibilities are endless.
To give one example from my shell history. Some times I have a dozens of pdf files open in my linux desktop (using evince pdf viewer) and I wanna restart the computer but don't want to lose track of which pdf files were open. There may be automated ways of doing this but let's say there aren't any. I start with ps ax:
ps ax | view -
A long log. I want to pick only lines that have evince:
ps ax | grep evince | view -
Now I included the 'grep evince' line too, which I don't want:
ps ax | grep evince | grep -v grep | view -
Good. But I don't care about all the columns of ps log, except for the last one (the one that shows the full path of the file). That's column 6:
ps ax | grep evince | grep -v grep | awk '{ print $6 }' | view -
Looks good. Generate a report file from this:
ps ax | grep evince | grep -v grep | awk '{ print $6 }' > openpdfs_YYYYMMDD.txt
Then I close all my pdfs, and reboot. And I don't know grep, awk except for very basic things like what I already did. But I know similar tidbits about many other commands. If I have to perform regex search only I use grep, but for search and replace I use sed. Sometimes cut is more handy for column selection than awk. If I don't know the command but I know what I need to do, I just google it, and 99% of the time, I can find a stackoverflow post where a linux based one-liner is mentioned which is pretty much a drop-in for my piping workflow.
Finally, if I want to traverse through each line of the entry and process one by one, I use the while loop. For example, if instead of dumping the file paths of the pdf I wanted to format it a little bit using directory name and file name, I'll do this:
ps ax | grep evince | grep -v grep | akw '{ print $6 }' | while read -r dfnam; do echo 'Directory:' $(dirname ${dfnam}) 'File:' $(basename ${dfnam}); done | view -
And again, view or dump.
Try this, and you would realize that the possibilities are endless.
- vram22 8y agoThis is a great technique; thanks for sharing it. While I knew about all the individual parts that you used, I don't think I ever thought of combining all the parts with the "view -" at end, although I knew that "-" as a command-line arg means standard input (to many commands that support it). Very useful stuff, and as you say, the possibilities are endless. I had done something sort of analogous, an experimental Python tool called pipe_controller, which is not about piping commands to each other in the traditional Unix sense; rather it is about "piping" the output of one function to a second one, and the output of the second to a third one, and so on, as many as one needs, under the control of a for loop. The net effect is like normal composition of function calls, like f(g(h(x))), but some other interesting effects can be achieved by doing it with a for loop, and changing some things at run time: After first creating pipe_controller (which is simple, really), I played around with using it in a few different ways, and found that it can be used for at least a couple of interesting things: - running a "pipe" (of those functions) incrementally (something like the technique you showed), and saving / viewing the output of each intermediate stage; - swapping components of the "pipe" at run time, under program control, which again can lead to some interesting use cases. I blogged a small series of posts about pipe_controller and such uses of it. Here are the two last or so posts, and the previous posts can be reached by following links in those posts: Swapping pipe components at runtime with pipe_controller: https://jugad2.blogspot.com/2012/10/swapping-pipe-components-at-runtime.html https://jugad2.blogspot.com/2012/10/swapping-pipe-components... Using PipeController to run a pipe incrementally: https://jugad2.blogspot.com/2012/09/using-pipecontroller-to-run-pipe.html https://jugad2.blogspot.com/2012/09/using-pipecontroller-to-... The pipe_controller code is here: https://bitbucket.org/vasudevram/pipe_controller https://bitbucket.org/vasudevram/pipe_controller
- vram22 8y agoAnother related couple of posts are about creating Unix pipelines under the control of a Python program: Generate PDF from a Python-controlled Unix pipeline: https://jugad2.blogspot.com/2016/01/generate-pdf-from-python-controlled.html https://jugad2.blogspot.com/2016/01/generate-pdf-from-python... Code for recent post about PDF from a Python pipeline: https://jugad2.blogspot.com/2016/01/code-for-recent-post-about-pdf-from.html https://jugad2.blogspot.com/2016/01/code-for-recent-post-abo...