Bash cookbook

Solutions to common problems.

Replacing newline characters

Comprehensively solved by this SO answer:

Use tr

tr '\n' ' ' < FILENAME

Tools like sed will not work, as they are fed line-by-line, and therefore never see newline characters.

sed

Alternative and escaped seperators

When using sed on e.g. urls, string characters like / can be bothersome, especially when stored in a variable. sed provides, however, the functionality to change the seperator.

In standard operations, this looks like

sed 's%ptrn1%replcm1%g'

where the character immediately after s denotes the seperator.

In other operations, such as delete, the same can be accomplished by escaping the first seperator:

sed '\|pattern to delete|d'

Multi-pattern with sed

To run several replacements with sed use

sed 's/ptrn1/replcm1/g; s/ptrn2/replcm2/g; ...'

nohup with sudo

A common design pattern is to background (&) a command with sudo with nohup. Naively sticking sudo as a prefix means that sudo will be run in the background, and not the nohup process. Instead, use the run as background process flag -b:

sudo -b nohup MY_COMMAND 

Command after time

To run a command after a certain time interval

sleep 60s && MY_COMMAND

Note: the use of && instead of e.g. ; is so that cancelling the sleep command also cancells MY_COMMAND.

To run a process and kill it after a certain amount of time, use

MY_COMMAND & pid=$! ; sleep 1m && kill $pid

Alternatively, background the termination process using a subshell

MY_COMMAND & pid=$! ; ( sleep 1m && kill $pid ) &

See this Stack Overflow answer for obtaining PIDs ahead of time.

Handling JSON

A very useful tool for handling JSON data in bash is the jq processor.

To extract a specific field, use

cat data.json | jq .nested.property

To index arrays use .[i] notation, where i is the index.

A full tutorial is available in the docs for more advanced usage.