Skip to content
Latchkey

sed Quoting Pitfalls in YAML CI Files

A sed command inside a CI run step passes through YAML and shell parsing before sed sees it, and each layer can mangle quotes.

Most sed CI failures are not sed bugs, they are quoting. The command travels through YAML, then the shell, then sed, and every layer has its own rules.

What it does

In a workflow run step, YAML reads the block, the shell parses the resulting string, and only then does sed receive its program. Single quotes around the sed program stop the shell from expanding $ and the slash, but a single quote inside the program ends the quoting early.

Common usage

Terminal
# safe: single-quoted program, no shell expansion
- run: sed -i 's/old/new/' config.yml

# need a shell variable? use double quotes and escape
- run: sed -i "s/version=.*/version=$NEW_VER/" app.ini

# a literal single quote in the program: end-quote, escaped quote, re-quote
- run: sed -i 's/it'\''s/it is/' file

Options

LayerPitfall
YAMLA program with : may need the whole run block quoted
Shell single quotesNo $ expansion, but no embedded single quote either
Shell double quotesAllows $VAR but the shell now eats $, \, and backticks
Embedded 'Close, write '\'', then reopen the quote
BackslashesDouble quotes may consume a \ before sed sees it

In CI

Default to single quotes around the sed program so the shell leaves it alone, and only switch to double quotes when you must interpolate a workflow variable. For multi-line YAML blocks, the | or > scalar styles change how newlines and quotes are read, so keep complex sed on one line.

Common errors in CI

An unbalanced quote yields the shell error sed: -e expression #1, char N: unterminated `s' command because the shell merged the program with the next token. Using double quotes around a replacement that contains $ or \1 lets the shell expand or strip it before sed runs, so the backreference vanishes.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →