Quick Tip #1: Implicit FIFOs in Bash

One could assume that I have run out of material and retreat to safer ground, but far from it. From now on I'll just throw in a few quick shell hacks hoping some of you don't know them yet. So, here it goes ...

Unix pipes are cool, but it's quite a limitation that a program can only read from a single pipe. Sure, there are named pipes, but it's a real pain to use them and we'd be leaving oneliner zone. Fortunately, recent versions of bash support implicit FIFOs that are created on demand by the shell. All you need is a bit of additional syntax.

Suppose you want to concatenate two compressed CSV files. The minor complication here is that you only want the header of the first file. With implicit FIFOs that's easily possible:

$ zcat data_1.csv.gz | cat - <(zcat data_2.csv.gz | sed 1d) > out.csv

The sed(1) command deletes the first line of its input stream removing the CSV file's header (one header should be enough in most cases). If you like symmetry, you can use this equivalent version:

$ cat <(zcat data_1.csv.gz) <(zcat data_2.csv.gz | sed 1d) > out.csv

In another use case you might want to check which files are in directory dir1 but not in dir2:

$ comm -23 <(ls dir1 | sort) <(ls dir2 | sort)

Try the following if you're interested in where the FIFO is created:

$ echo <(echo test)

There are implicit FIFOs for output, too, but I never found a good use case for them (maybe they're useful for complex tee(1) constructs). For more information see section "Process Substitution" in your bash(1) man page.

social