Here’s a little bash trick you might not be aware of.
If you wrap a command in <(
and )
, you get back something that looks like a file name;
$ echo <(ls)
/dev/fd/63
now, that’s not a file, but a file descriptor – a temporary path that unix programs can be tricked into treating like a file.
For example, you can cat
the file descriptor just as you would a file:
$ cat <(ls)
Applications
Desktop
Documents
Downloads
So cat
thinks it’s reading a file – cat /dev/fd/63
– but it’s actually streaming the output of a command.
So with this trick, any program that takes a file parameter can take a command output. Eg;
curl
some web content- use
find
orls
to describe files - use
sed
,awk
, andgrep
to modify an existing file
This can be useful when you have a program that takes multiple input files, like diff;
$ diff <(ls src) <(ls src.bak)
3d2
< canto34-syntax.test.ts
5d3
< canto34.test.ts
7d4
< example.test.ts
So here I’ve listed the contents of two directories of source files, and I can see that src
has three more files in it than src.bak
. Now that’s hard to do otherwise!
Or consider this example – I’ve got two files I know differ only by indentation:
$ diff src/example.ts src.bak/example.ts | wc -l
82
so, lots of differences. But can I prove they’re the same after trimming?
$ diff <(sed 's|^ *||' src/example.ts) <(sed 's|^ *||' src.bak/example.ts)
<no output>
Ok then! I’ve used sed
to trim leading whitespace from both files, and now the diff is empty – the files are basically the same.