5 ms·
Once you discover <() it's hard not to (ab)use it everywhere :-) # avoid temporary files when some program needs two inputs: join -e0 -o0,1.1,2.1 -a1 -
by unhammer 12y ago
Once you discover <() it's hard not to (ab)use it everywhere :-)
# avoid temporary files when some program needs two inputs:
join -e0 -o0,1.1,2.1 -a1 -a2 -j2 -t$'\t' \
<(sort -k2,2 -t$'\t' freq/forms.${lang}) \
<(sort -k2,2 -t$'\t' freq/lms.${lang})
# gawk doesn't care if it's given a regular file or the output fd of some process:
gawk -v dict=<(munge_dict) -f compound_translate.awk <in.txt
# prepend a header:
cat <(echo -e "${word}\t% ${lang}\tsum" | tr [:lower:] [:upper:]) \
<(coverage ${lang})
- repsilat 12y ago> # gawk doesn't care if it's given a regular file or the output fd of some process: Something wonderful I found out the other day: Bash executes scripts as it parses them, so you can do all kinds of awful things. For starters, bash <(yes echo hello) will have bash execute an infinite script that looks like echo hello echo hello echo hello ... without trying to load the whole thing first. After that, you can move onto having a script append to itself and whatever other dreadful things you can think of.
- unhammer 12y agoThat's actually one of the things that I really dislike with bash, that it doesn't read the whole script before executing it. I've been bitten by it before, when I write some long-running script, then e.g. write a comment at the top of it as it's running, and then when bash looks for the next command, it's shifted a bit and I get (at best) a syntax error and have to re-run :-(
- lsaferite 12y agoEwww. Thats... nasty and dangerous. Very dangerous.
- LukeShu 12y agoThere are several ways to get Bash to read the whole thing before executing. My preferred method is to write a main() function, and call main "$@" at the very end of the script. Another trick, useful for shorter scripts, is to just wrap the body of the script in {}, which causes the script to be a giant compound command that is parsed before any of it is executed; instead of a list of commands that is executed as read.
- unhammer 12y agoAh, thank you for that. I may just start using these tricks in all my scripts :-)
- thristian 12y agoFun fact: That's how goto worked in the earliest versions of Unix, before the Bourne shell was invented: goto was an external command that would seek() in the shell-script until it found the label it was looking for, and when control returned to the shell it would just continue executing from the new location. To this day, when the shell launches your program, you can find the shell-script it's executing as file-descriptor 255, just in case you want to play any flow-control shenanigans.
- jquast 12y agoone of my favorites is using diff across output of two programs, diff thinks they are files: diff -u <(zipinfo archive.zip.bak) <(zipinfo archive.zip)