if test; then ... elif test; then ... else ... fi
test
can be:
if
will switch on the exit result of the command.[[ expression ]]
. The expression can use standard comparison operators (==, !=, >, >=
) etc.(( expression ))
. This works on integers only.Be careful with spaces. In general put spaces around everything since the double brackets are actually commands and need to be obviously separated from the expressions.
Allows you to treat the stdout of a command as a file input to another command. In Z Shell there are two variants:
<()
creates a FIFO to hold the sub-command's output (which is removed on completion). This also works in Bash.=()
creates a temporary file (in /tmp
which is removed on completion) which is much more reliable — if a FIFO doesn't work, this might. This is Z Shell only.The <()
expression returns the path to the FIFO that holds the sub-command's output via command substitution. Likewise, =()
returns the path to the temporary file. You can see this using:
echo <(echo foo) echo =(echo foo)
Example — diff
a local file against the output of another command:
diff -day --color localfile <(othercommand)
FYI — the parameters for the diff
command here are:
Grep doesn't support capture groups, but you can fake it with a combination of Perl look-behind/ahead groups and --only-matching
to exclude things. Basically we are using groups to exclude stuff we don't want rather than capture the stuff we do want:
grep --only-matching --perl-regexp "(?<=excluded start stuff)captured stuff(?=excluded end stuff)"
This works pretty well so long as the groups are fixed length — you can't use wild-cards in the look-behind/ahead groups, but you can in the non-group text.
Something I regularly need to do is format a chunk of unformatted JSON. This can be done using:
read json; echo ${json} | jq .
Run the command, then paste the JSON into the terminal.
The read var; echo ${var} | some_command
technique is handy for processing chunks of text without creating temporary files.