7 ms·
Well, a bash for loop is pretty close to Python: for x in a b c; do echo $x done Or ranges: for i in {1..10}; do echo $i; done Do you me
by dfinninger 4y ago
Well, a bash for loop is pretty close to Python:
for x in a b c; do
echo $x
done
Or ranges:
for i in {1..10}; do echo $i; done
Do you mean list comprehensions?
- intrepidhero 4y agoThe number one use case of `for` in shell scripting is over the output of `$(ls .)` And I immediately run into a problem with filenames that have spaces and then I discover that a stringly typed language has lots of sharp edges. I fall back on `for filename in os.listdir():`
- npongratz 4y agoIf I may humbly offer a suggestion, looping over filenames should [edit: almost] never be done with ls. find can be used with much better fidelity: https://www.shellcheck.net/wiki/SC2012 https://www.shellcheck.net/wiki/SC2012 "ls is only intended for human consumption: it has a loose, non-standard format and may "clean up" filenames to make output easier to read."
- cb321 4y agoShells usually do not re-split on whitespace after filename generation. So, you could also just use an asterisk for your number one use case: dash$ touch "hi ho" dash$ touch "there, buddy" dash$ for f in *; do echo $f; done hi ho there, buddy (EDIT: That was in a scratch directory.) But as @npongratz alludes to in sibling https://news.ycombinator.com/item?id=34727735 https://news.ycombinator.com/item?id=34727735 find . [predicates] -print0 | xargs -0 is bulletproof and directory scanning, output, and input loops all run at full C speed. (One predicate is `-maxdepth 1` to not recurse.)
- dolmen 4y agoTry this: touch -- -n
- cb321 4y agoI'm sure the full list of shell check rules is in the many dozens.. I was just trying to address one apparent misperception. And here I thought someone would complain about not putting $f in double quotes not * instead of ./* ;-) Anyway, I did mention find-xargs, but it's also true your leading dash filenames mistaken for options point can cause trouble in naive invocations if find roots begin with dashes. Doubtless, a lotta gotchas..
- tp34 4y ago[flagged]
- Karellen 4y agoFWIW, if you need to use `sh` instead of `bash` for some reason, you can do the range loop with: for i in $(seq 1 10); do echo $i; done
- chasil 4y agoThe seq command is not POSIX. Only rely upon it when GNU is a focus, which is not everywhere. These are the POSIX utilities: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ https://pubs.opengroup.org/onlinepubs/9699919799/utilities/
- Karellen 4y agoHuh. Why did I misremember that? I knew `seq` was available on BSDs. For some reason I thought it was on SVr4-derived Unices too (and therefore figured it was either actually Posix, or ubiquitous enough to be reliable anyway), but I guess I got that one wrong. Maybe because GNU tends to be a bit more heavily influenced by SVr4 than BSD, historically? Anyway, thanks for the correction.
- dolmen 4y agoseq being available on BSDs doesn't mean either that it comes from POSIX.
- Karellen 4y agoSorry, didn't mean to imply that. The point I was making is that because (to my recollection) GNU tends to mimic SVr4, the fact that `seq` is in GNU is probably why I thought it was also available in SVr4-derived Unices. But also, I know that `seq` is in the BSDs. Therefore, if `seq` were in GNU, SVr4 and the BSDs, then a) the chances that it would have been included in Posix are very high, and b) even if it wasn't in Posix, the fact that it's in all 3 of those families of shell tools would make it ubiquitous enough that I'd be happy to rely on it for a personal project that I intended to be widely portable anyway. (Posix tends to codify existing common practice, rather than designing new features for existing systems to implement.)