Every once in a while I accidentally discover a useful and clever trick and no matter how hard I try, I cannot find it in any sort of documentation. This bash trick is one of my favorites.
Sometimes you want to use a bash command that takes a file as an argument but you don’t actually have a file but another command that creates it or something like that. So what you would normally do is to create a temporary file, use it and delete it afterwards. That’s not so complicated but the extra steps might be annoying and interrupt your flow. What if the command you want to use is part of a one-liner and it would really be a shame to “ctrl-c” the whole thing to create the temporary files, wouldn’t it?
The trick is simple then, all you have to do is put the command that creates the temporary file you want to use inside “<( )” and you’re done. For example, let’s say you have two files, one has 1000 lines and the other has 100 and you want to paste them. Let’s say you don’t want empty spaces on the 900 uncommon lines, so you want the head of the 1000 line file. Now instead of doing:
head -100 1000_line_file.txt > tmpfile
paste tmpfile 100_line_file.txt > pasted.txt
You can do it in one line:
paste 100_line_file.txt <(head -100 1000_line_file.txt)
What’s going on being the scenes there is bash actually creates a file descriptor out of the command you put in the parentheses and gives it to the main command (paste, in this example), you can see this happen if you write something like:
ls <(head -100 1000_line_file.txt)
Such a simple yet hardly documented feature, I’m sure remembering this little fellow exists will make your life easier some day.
And you’ll get a result similar to:
Such a lovely trick, yet hardly documented. I’m sure it will make your life easier some day, just try to remember it exists.