DEV Community

dpm_bush
dpm_bush

Posted on Originally published at sshflow.com

Practical sed: Replace Text and Select Lines Safely

sed is useful when a shell pipeline needs to change text or keep only particular lines. Its safest default is also easy to overlook: it prints transformed output to the terminal and leaves the input file alone. That makes it practical to preview an edit before deciding whether to change the original.

Think in terms of input, address, and command

sed reads input one line at a time. An expression can include an optional address that chooses which lines to act on, followed by a command that says what to do:

sed 'address command' file
Enter fullscreen mode Exit fullscreen mode

For example, this changes the first old on each line of the output:

printf '%s\n' 'host=old.example' | sed 's/old/new/'
Enter fullscreen mode Exit fullscreen mode

The result is host=new.example. The input file is untouched; here, the input is a pipeline rather than a file.

Quotes keep the expression together as one argument. Single quotes are a useful default for fixed expressions because they prevent the shell from expanding special characters such as $ before sed receives them.

Replace text with s

The substitution command has this shape:

s/pattern/replacement/flags
Enter fullscreen mode Exit fullscreen mode

By default, it replaces only the first match on each line. Add g to replace every match on each line:

printf '%s\n' 'red red red' | sed 's/red/blue/'
printf '%s\n' 'red red red' | sed 's/red/blue/g'
Enter fullscreen mode Exit fullscreen mode

The first output line is blue red red; the second is blue blue blue.

A pattern can be a regular expression, not just literal text. In a regular expression, . matches any single character. If your pattern or replacement contains /, you can choose another delimiter to make the expression easier to read:

printf '%s\n' '/srv/old/site' | sed 's#/srv/old#/srv/new#'
Enter fullscreen mode Exit fullscreen mode

This prints /srv/new/site. If the delimiter you chose appears inside the pattern or replacement, escape it with a backslash. In replacement text, & stands for the complete match; write \& when you want a literal ampersand.

You can also limit a substitution to a particular line. This changes only the first draft on line 2:

sed '2s/draft/published/' notes.txt
Enter fullscreen mode Exit fullscreen mode

Select or remove lines

Sed prints every input line by default. Use -n to suppress that output, then p to print only lines that match an address:

sed -n '2p' file.txt
sed -n '/error/p' application.log
Enter fullscreen mode Exit fullscreen mode

The first command prints line 2. The second prints lines containing error. If you only need to find matching lines, grep is often the simpler choice; this guide to searching with grep covers that side of the job.

The d command removes addressed lines from the output. It does not delete them from the input file unless you also request in-place editing:

printf '%s\n' keep skip keep | sed '/skip/d'
Enter fullscreen mode Exit fullscreen mode

The output contains two lines: keep and keep.

Addresses can be line numbers or ranges. For example, these print lines 2 through 4, or omit them from the output:

sed -n '2,4p' file.txt
sed '2,4d' file.txt
Enter fullscreen mode Exit fullscreen mode

A range can also start and end at patterns. This prints the lines from a BEGIN match through an END match, including the boundary lines:

sed -n '/BEGIN/,/END/p' file.txt
Enter fullscreen mode Exit fullscreen mode

Combine small edits in a pipeline

You can run multiple commands in one expression, separated by semicolons. This example changes every draft on a line, then removes blank lines:

sed 's/draft/final/g; /^$/d' report.txt
Enter fullscreen mode Exit fullscreen mode

Sed is a good fit for compact, line-based transformations. If your task needs field-aware processing or calculations, awk may be easier to follow. When you want to display command output and save it at the same time, tee can pass output along while writing a file.

Preview before editing a file

Run the command without -i first. For example, preview a replacement in a configuration file:

sed 's/old.example/new.example/g' app.conf
Enter fullscreen mode Exit fullscreen mode

Inspect the output before applying the change. In-place editing can overwrite a configuration file, so make a recoverable copy and verify the result before using it in a production environment.

The syntax for -i differs between common sed implementations. With GNU sed, this form edits the file and creates a backup named app.conf.bak:

sed -i.bak 's/old.example/new.example/g' app.conf
Enter fullscreen mode Exit fullscreen mode

BSD/macOS sed uses a separate suffix argument when creating a backup:

sed -i '.bak' 's/old.example/new.example/g' app.conf
Enter fullscreen mode Exit fullscreen mode

Its no-backup form is:

sed -i '' 's/old.example/new.example/g' app.conf
Enter fullscreen mode Exit fullscreen mode

That last command edits the original without creating a backup. If you use it, keep a separate copy first. When a script needs to run on multiple platforms, check the target system's man sed and test the command on sample input; GNU-specific features and in-place syntax are not universal.

I originally published a more detailed version of this guide on the SSHFlow blog.

I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.

Top comments (0)