Also, it really isn't 10-20 lines to spit out the contents of some files in Python:
>>> filelist = ["tmp.pl", "tmp.go", "Tmp.hs"]
>>> for f in filelist:
... print(open(f).read())
It's trivial to code golf that down to 1 line, but if we're writing in Python at any sort of scale, this is more realistic. Easy things are still generally easy. They just aren't optimized down to shell level in terms of keystroke count. They're often more optimized than bash in terms of conceptual complexity, though.For instance, if one of my files has a space in it, shell becomes a conceptual minefield, requiring you to understand the half-a-dozen ways it might process strings and how that interacts with filenames and arguments passed to commands, whereas the Python just keeps doing what you probably meant, because it knows what's a string and what's something else. Shell makes a lot of sacrifices for that concision, and there's a lot of "Well, this will probably be OK on anything I run it on...". I never put spaces in my file name, but use periods or underscores instead, precisely so I don't screw myself over with shell. I shouldn't have to do that. Personally I think the crossover point is in the high single digit number of bash lines. The only advantage bash still holds over Python at that point is large pipelines, and 80% of those can be replaced by Python functions. For the remainder, use a pipelining library.
for i in ‘ls /tmp/foo’; do echo $i | grep bar | cut -d’-‘ -f3,4; done
Is just so much easier to remember than Python’s OS library, right? I can intuitively string that together but can’t write python without looking up the docs and reading a paragraph about idiosyncrasies.Your code also breaks if the filenames have spaces:
$ ls -1
bar-def-gh i-jkl-mno-p
bar-def-ghi-jkl-mno-p
$ for i in `ls`; do echo $i | grep bar | cut -d- -f3,4; done
gh
ghi-jkl
The natural Python code you'd write to replace it will do what you expect and print the file with a space in it in the way you'd expect. You can fix this in bash via "for i in [asterisk]" (or, in this case, "for i in [asterisk]bar[asterisk]"), but, well, remember when I said bash requires you to understand the half-a-dozen ways strings and filenames interact...? In Python, there's just the one way that strings work.(HN is forcing me to say [asterisk]. AFAIK there's still no escaping for them.)
You lucked out a bit here too; I don't think I can get echo to do anything very interesting based on file names. Had you interpolated that somewhere more interesting I'd give you some security issues too, if anybody not trusted can create files, which, again, the naive Python code would be much more robust to, because in Python, you have to explicitly ask to bring a string up to an execution context or a function parameter context, unlike shell's complicated rules for interleaving them. You pay a steep price for the convenience.
Of course, this is a matter of scale. I use that sort of pipeline interactively every day. I just start shuddering when it goes in a file for a script, and shudder more if it goes into source control.
And then the parent even specifically pointed out that files with spaces would be a minefield.
Also complaining about looking up docs is just a matter of where you have your knowledge. I would have the opposite problem to understand the "idiosyncrasies" of what the -d flag into cut does whereas I know the python standard library by heart.
On the plus side, when I fixed the typographical issues, it did work. I'm pretty sure I could do this more-or-less first-time right in Python, too, but it clearly took me longer to get there.
As for file names not having spaces in them, after I said I personally don't use spaces in my file names,
find -name '* *' | wc -l
on my home directory here yielded 12985. Uncompressed archives I'm not the source of. Dot directions I did not creat. Some tmp files. Probably the majority of my media files, which are the bulk of that number, named in all sorts of different ways that only share in common that I didn't pick them. An Anki directory. Yeah. They happen.(Also, because I know someone's gonna try to go for the zinger here, I am not being hypocritical. I do not have an objection to one-off scripting jobs, especially ones like this that are read-only so there is no permanent consequence for error.)
This is a cop out. File names can totally contain spaces, and the difference between the Bash and Python solution is that one will continue to work when a file with spaces inevitably shows up and one will fail, possibly silently.
Also with something like Gnu Parallel you can easily scale across multiple machines. Maybe there are more efficient approaches but a pipeline and gnu parallel is pretty easy to scale up without thinking much about it.
https://www.youtube.com/watch?v=Sg4U4r_AgJU
I'll admit, I'm no fan of Python, but this has little to do with the language itself. I found Bash and Ruby first, so Python just seems like too much work to get right.
Requisite xkcd: https://xkcd.com/1987/