CrackOps
Interview PrepTracksLinuxAWS LabSoonInterview RoomSoon
Sign inStart free
CrackOps

Interview prep for the people who keep production up.

[email protected]
ProductInterview PrepTracksDashboardInterview Room
RolesDevOpsSREPlatformCloud
CompanyAboutContactPrivacyTerms
© CrackOps
Linux / Text Processing / sed

sed

Stream editor: find and replace, delete and print lines

Intermediateconfigregexin-placelogs

sed edits text as it streams past: substitute one string for another, delete or print ranges of lines, insert lines. It is how you change a config value in a script without opening an editor, mask secrets before sharing a file, or cut a time window out of a huge log.

Syntaxsed [-n] [-E] [-i[SUFFIX]] 'SCRIPT' [FILE]...

Watch it run

You are about to promote a staging config to production and want to see exactly what a global replace would change.

devops@devops-lab: ~/app/config — zsh — 96×28
➜ ~/app/config
Step 1 of 3
sed 's/staging/production/g' app.env

Without -i, sed only prints the edited text; the file is untouched. The g flag replaced every match on each line. Note what else changed: the comment and three hostnames, but not 'Staging' with a capital S.

Anatomy of a command

$ '///'
commandsed

The stream editor: reads input line by line, runs the script on each line, prints the result.

How it works

sed reads one line at a time into a buffer called the pattern space, strips the newline, and runs every command of the script against it in order. At the end of the script (the end of the cycle) it prints the pattern space, unless -n was given, then loads the next line. Commands can be limited by an address: a line number (5), a regex (/^DB_/), a range (/start/,/end/) or $ for the last line. d deletes the pattern space and starts the next cycle early, p prints it, and a second buffer, the hold space, can keep text between lines (h, g, x). With -i, sed writes the output to a temporary file in the same directory and then rename()s it over the original. That means the file gets a new inode: hard links are broken, ownership can change if root edits a user's file, and a process that had the old file open keeps the old content.

sed loads each line into the pattern space, runs the script on it, prints it, and with -i swaps a new file in at the end.

line 3run commandsh g xprintapp.envinput fileScripts/debug/info/Pattern spacecurrent lineLOG_LEVEL=debugHold spacekept across linesstdoutterminal or pipeTemp file./sedK3x9Qaapp.envnew inode
1/8
Read one line

sed reads the next line of input, removes its newline and puts it in the pattern space. Only one line is in memory, so sed handles files of any size.

← → to step

Options you'll actually use

s/a/b/Substitute the first match of a on each line with b
s/a/b/gg flag: replace every match on the line, not just the first
-nDon't print every line automatically; only what p prints
-i / -i.bakEdit files in place (GNU); with a suffix, keep a backup
-EExtended regex: ( ) + ? | {n} without backslashes
-e SCRIPTAdd a command; use several -e for several edits in one pass
Np / N,MpPrint line N or lines N to M (with -n)
/re/dDelete lines matching the regex
/start/,/end/pPrint from the first line matching start to the next matching end
s|a|b|Any character can be the delimiter: handy when the text contains /
a\ i\ c\Append after, insert before, or change the addressed line
$=With -n, print the number of the last line (a line count)

Common mistakes

sed -i 's/old/new/' file on macOS

BSD sed requires a suffix argument after -i, so it treats your script as the suffix and fails with 'invalid command code'. Scripts that must run on both break here.

sed -i.bak 's/old/new/' file # works on GNU and BSD sed
sed 's/staging/prod/' app.env > app.env

The shell truncates app.env before sed runs, so sed reads an empty file and you lose the config.

sed -i.bak 's/staging/prod/' app.env
sed 's/$OLD/$NEW/' config (in single quotes)

Inside single quotes the shell doesn't expand variables, so sed searches for the literal text $OLD.

sed "s|$OLD|$NEW|" config # double quotes, and a delimiter not found in the values
sed -i 's/127.0.0.1/10.0.2.11/' hosts

In the regex, . matches any character, so 127a0b0c1 or 127.0.0.10 (prefix) would also match. Rarely a problem until it is.

sed -i 's/127\.0\.0\.1\b/10.0.2.11/' hosts
Running sed -i in a deploy without checking the result

If the pattern doesn't match (someone changed the file), sed exits 0 and changes nothing. The deploy carries on with the old value.

sed -i 's/^X=.*/X=1/' f && grep -qx 'X=1' f || { echo 'edit failed'; exit 1; }

Interview questions

Practice

Try these on a Linux machine of your own. Each task has a hint and a solution.

  1. 1

    Print lines 10 to 20 of /var/log/app/app.log without changing anything.

  2. 2

    Make a copy of ~/app/config/app.env with every comment line and blank line removed, saved as clean.env.

  3. 3

    Change LOG_LEVEL to warn in ~/app/config/app.env, in place, keeping a .bak backup. Then prove what changed.

  4. 4

    Show ~/app/config/app.env with any value of a key ending in PASSWORD replaced by ****.

Related commands

grepSearch text for lines that match a patternawkProcess text by columns: filter, sum, count and reporttrTranslate, squeeze or delete charactersdiffCompare files and directories line by linevimEdit files on any server with vim
PreviousgrepNextawk
Linux / Text Processing / sed

sed

Stream editor: find and replace, delete and print lines

Intermediateconfigregexin-placelogs

sed edits text as it streams past: substitute one string for another, delete or print ranges of lines, insert lines. It is how you change a config value in a script without opening an editor, mask secrets before sharing a file, or cut a time window out of a huge log.

Syntaxsed [-n] [-E] [-i[SUFFIX]] 'SCRIPT' [FILE]...

Watch it run

You are about to promote a staging config to production and want to see exactly what a global replace would change.

devops@devops-lab: ~/app/config — zsh — 96×28
➜ ~/app/config
Step 1 of 3
sed 's/staging/production/g' app.env

Without -i, sed only prints the edited text; the file is untouched. The g flag replaced every match on each line. Note what else changed: the comment and three hostnames, but not 'Staging' with a capital S.

Anatomy of a command

$ '///'
commandsed

The stream editor: reads input line by line, runs the script on each line, prints the result.

How it works

sed reads one line at a time into a buffer called the pattern space, strips the newline, and runs every command of the script against it in order. At the end of the script (the end of the cycle) it prints the pattern space, unless -n was given, then loads the next line. Commands can be limited by an address: a line number (5), a regex (/^DB_/), a range (/start/,/end/) or $ for the last line. d deletes the pattern space and starts the next cycle early, p prints it, and a second buffer, the hold space, can keep text between lines (h, g, x). With -i, sed writes the output to a temporary file in the same directory and then rename()s it over the original. That means the file gets a new inode: hard links are broken, ownership can change if root edits a user's file, and a process that had the old file open keeps the old content.

sed loads each line into the pattern space, runs the script on it, prints it, and with -i swaps a new file in at the end.

line 3run commandsh g xprintapp.envinput fileScripts/debug/info/Pattern spacecurrent lineLOG_LEVEL=debugHold spacekept across linesstdoutterminal or pipeTemp file./sedK3x9Qaapp.envnew inode
1/8
Read one line

sed reads the next line of input, removes its newline and puts it in the pattern space. Only one line is in memory, so sed handles files of any size.

← → to step

Options you'll actually use

s/a/b/Substitute the first match of a on each line with b
s/a/b/gg flag: replace every match on the line, not just the first
-nDon't print every line automatically; only what p prints
-i / -i.bakEdit files in place (GNU); with a suffix, keep a backup
-EExtended regex: ( ) + ? | {n} without backslashes
-e SCRIPTAdd a command; use several -e for several edits in one pass
Np / N,MpPrint line N or lines N to M (with -n)
/re/dDelete lines matching the regex
/start/,/end/pPrint from the first line matching start to the next matching end
s|a|b|Any character can be the delimiter: handy when the text contains /
a\ i\ c\Append after, insert before, or change the addressed line
$=With -n, print the number of the last line (a line count)

Common mistakes

sed -i 's/old/new/' file on macOS

BSD sed requires a suffix argument after -i, so it treats your script as the suffix and fails with 'invalid command code'. Scripts that must run on both break here.

sed -i.bak 's/old/new/' file # works on GNU and BSD sed
sed 's/staging/prod/' app.env > app.env

The shell truncates app.env before sed runs, so sed reads an empty file and you lose the config.

sed -i.bak 's/staging/prod/' app.env
sed 's/$OLD/$NEW/' config (in single quotes)

Inside single quotes the shell doesn't expand variables, so sed searches for the literal text $OLD.

sed "s|$OLD|$NEW|" config # double quotes, and a delimiter not found in the values
sed -i 's/127.0.0.1/10.0.2.11/' hosts

In the regex, . matches any character, so 127a0b0c1 or 127.0.0.10 (prefix) would also match. Rarely a problem until it is.

sed -i 's/127\.0\.0\.1\b/10.0.2.11/' hosts
Running sed -i in a deploy without checking the result

If the pattern doesn't match (someone changed the file), sed exits 0 and changes nothing. The deploy carries on with the old value.

sed -i 's/^X=.*/X=1/' f && grep -qx 'X=1' f || { echo 'edit failed'; exit 1; }

Interview questions

Practice

Try these on a Linux machine of your own. Each task has a hint and a solution.

  1. 1

    Print lines 10 to 20 of /var/log/app/app.log without changing anything.

  2. 2

    Make a copy of ~/app/config/app.env with every comment line and blank line removed, saved as clean.env.

  3. 3

    Change LOG_LEVEL to warn in ~/app/config/app.env, in place, keeping a .bak backup. Then prove what changed.

  4. 4

    Show ~/app/config/app.env with any value of a key ending in PASSWORD replaced by ****.

Related commands

grepSearch text for lines that match a patternawkProcess text by columns: filter, sum, count and reporttrTranslate, squeeze or delete charactersdiffCompare files and directories line by linevimEdit files on any server with vim
PreviousgrepNextawk