sedStream editor: find and replace, delete and print lines
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.
sed [-n] [-E] [-i[SUFFIX]] 'SCRIPT' [FILE]...You are about to promote a staging config to production and want to see exactly what a global replace would change.
sedThe stream editor: reads input line by line, runs the script on each line, prints the result.
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.
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.
s/a/b/Substitute the first match of a on each line with bs/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 passNp / 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 ends|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)sed -i 's/old/new/' file on macOSBSD 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 sedsed 's/staging/prod/' app.env > app.envThe 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.envsed '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 valuessed -i 's/127.0.0.1/10.0.2.11/' hostsIn 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/' hostsRunning sed -i in a deploy without checking the resultIf 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; }Try these on a Linux machine of your own. Each task has a hint and a solution.
Print lines 10 to 20 of /var/log/app/app.log without changing anything.
Make a copy of ~/app/config/app.env with every comment line and blank line removed, saved as clean.env.
Change LOG_LEVEL to warn in ~/app/config/app.env, in place, keeping a .bak backup. Then prove what changed.
Show ~/app/config/app.env with any value of a key ending in PASSWORD replaced by ****.
sedStream editor: find and replace, delete and print lines
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.
sed [-n] [-E] [-i[SUFFIX]] 'SCRIPT' [FILE]...You are about to promote a staging config to production and want to see exactly what a global replace would change.
sedThe stream editor: reads input line by line, runs the script on each line, prints the result.
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.
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.
s/a/b/Substitute the first match of a on each line with bs/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 passNp / 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 ends|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)sed -i 's/old/new/' file on macOSBSD 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 sedsed 's/staging/prod/' app.env > app.envThe 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.envsed '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 valuessed -i 's/127.0.0.1/10.0.2.11/' hostsIn 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/' hostsRunning sed -i in a deploy without checking the resultIf 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; }Try these on a Linux machine of your own. Each task has a hint and a solution.
Print lines 10 to 20 of /var/log/app/app.log without changing anything.
Make a copy of ~/app/config/app.env with every comment line and blank line removed, saved as clean.env.
Change LOG_LEVEL to warn in ~/app/config/app.env, in place, keeping a .bak backup. Then prove what changed.
Show ~/app/config/app.env with any value of a key ending in PASSWORD replaced by ****.