Replace a pattern in a file in a portable way

f=/path/to/file; sed -e "s/pattern/replacement/" "$f" > "$f".bak && mv "$f".bak "$f"

November 22, 2023bashoneliners

Explanation

At a high level, this involves two main steps:

  • Read the input file, replace the pattern and write to a backup file.
  • Move the backup file to the original file, replacing the original file.

We use sed ("stream editor for filtering and transforming text") to read the content of the file and replace the regex pattern. With the -e flag we specify an expression to execute, in this example a pattern replacement.

sed prints its output on standard output (stdout), we use > "$f".bak to redirect that to a backup file.

We chain an mv command after sed with && to ensure that we only perform the mv command if the sed command was successful.

Although sed has an -i flag to manipulate the input file in-place without needing a backup file as in this example, unfortunately the behavior of this flag depends on the implementation of sed.

The GNU equivalent of the one-liner:

sed -ie "s/pattern/replacement/" "$f"

The BSD equivalent of the one-liner:

sed -i .bak -e "s/pattern/replacement/" "$f" && rm "$f"