sed processes input line by line, applies your commands, and writes the result to standard output. The original file stays untouched unless you pass the -i flag. This makes it safe to preview any operation before committing it.
The general form of the delete command is:
bashsed 'ADDRESSd' file
ADDRESS selects which lines to delete. d is the delete command. Lines that do not match the address print as usual.
Delete a specific line by number:
bashsed '3d' file.txt # delete line 3sed '$d' file.txt # delete the last line
$ always refers to the last line regardless of file length, useful when you need to remove a trailing entry without counting lines first.
Delete multiple non-consecutive lines by separating addresses with a semicolon:
bashsed '2d;5d;8d' file.txt
Delete a block of consecutive lines with a range:
bashsed '3,6d' file.txt # delete lines 3 through 6sed '5,$d' file.txt # delete from line 5 to end of file
Adding ! after an address inverts the selection — it deletes everything that does NOT match. To keep only lines 3 through 5 and remove the rest:
bashsed '3,5!d' file.txt
This is a compact alternative to chaining head and tail to extract a slice.
GNU sed supports the first~step step address, which matches every Nth line starting at a given offset. To delete every even-numbered line:
bashsed '0~2d' file.txt
The offset 0 means the first match falls on line 2 (before the file starts, step of 2, so first match = line 2). To delete every third line starting from line 3:
bashsed '3~3d' file.txt
The first~step syntax is GNU sed only. It is not available in the BSD sed shipped with macOS.
Wrap a search pattern in slashes to delete matching lines:
bashsed '/error/d' file.txt
Pattern matching is a substring match — /bl/d would delete any line containing “bl”, including “black”. Be precise with your patterns.
To match case-insensitively, add the I flag after the closing slash:
bashsed '/Error/Id' file.txt
To invert the match and delete all lines that do NOT contain the pattern:
bashsed '/error/!d' file.txt
Use two patterns separated by a comma to delete a range between matching lines:
bashsed '/start/,/end/d' file.txt
sed starts deleting at the first line matching the opening pattern and stops after the first match of the closing pattern. Both endpoints are included in the deletion.
Mix a line number with a pattern when you know where the range starts but not where it ends:
bashsed '1,/header_end/d' file.txt
Remove truly empty lines with ^$ — the beginning anchor immediately followed by the end anchor:
bashsed '/^$/d' file.txt
This does not catch lines that contain only spaces or tabs. To remove those as well, use the POSIX [[:space:]] character class:
bashsed '/^[[:space:]]*$/d' file.txt
* matches zero or more whitespace characters, so this covers both empty lines and visually blank lines.
The pattern between slashes is a full regular expression:
bashsed '/^#/d' config.txt # strip comment lines starting with #sed '/;$/d' source.txt # remove lines ending with semicolonsed -E '/^.{0,4}$/d' file.txt # delete lines shorter than 5 characters -E enables extended regular expressions — no need to escape { and }.
You can chain multiple commands in one expression. Commands execute left to right, and deleted lines never reach later ones:
bashsed '/^#/d; s/localhost/127.0.0.1/g' config.txt
This strips comment lines first, then applies the substitution only to remaining lines.
All the examples above write to standard output. To modify the file permanently, add -i:
bashsed -i '/^$/d' file.txt
Always preview without -i first. When ready, pass a suffix to save an automatic backup:
bashsed -i.bak '/^$/d' file.txt
This saves the original as file.txt.bak before modifying file.txt.
Never redirect output to the same input file — the shell truncates it before sed reads it:
bashsed '/^$/d' file.txt > file.txt # destroys the file
On macOS, BSD sed requires an explicit extension argument even when you do not want a backup file:
bashsed -i '' '/^$/d' file.txt
Use line numbers for exact positions, ! to invert selection, patterns for content-based deletion, and [[:space:]] for blank line cleanup. Always preview without -i first, and use -i.bak when editing in place. Leave a comment below if you run into any issues.
The id command prints user and group identity for any account on the system. It shows the…
Linux provides two main tools for renaming directories: mv for single renames and the rename utility for batch pattern-based…
The w command in Linux shows who is currently logged in to the system and what each…
The sysctl command reads and modifies Linux kernel parameters from the command line. Changes take effect immediately…
The whereis command locates the binary, source, and manual page files for a given command. Unlike which, it…
git clone copies an existing Git repository into a new directory on your local machine. It…