/commands/sed/sed-insert-line-after-match
sed insert a line after or before a matching line (a and i commands)
- tool
- sed
- versions
- GNU sed 4.x, BSD sed (macOS)
- os
- linux, macos, windows
sed '/pattern/a new line' file adds new line after every line that matches pattern, and sed '/pattern/i new line' file adds it before. Add -i to change the file in place. You can also use a line number instead of a pattern (sed '3a text', sed '$a text' for the end of the file). The one-line form a text is a GNU extension; on macOS write the text on its own line after a\.
Example
cat > nginx.conf <<'EOF'
server {
listen 80;
server_name example.test;
}
EOF
sed '/listen 80;/a\ listen [::]:80;' nginx.conf
echo ===
sed '/^server {/i # managed by deploy script' nginx.conf
echo ===
sed -i '$a # end of file' nginx.conf
tail -n 2 nginx.confOutput
server {
listen 80;
listen [::]:80;
server_name example.test;
}
===
# managed by deploy script
server {
listen 80;
server_name example.test;
}
===
}
# end of fileThe first command adds the IPv6 listen line after the IPv4 one; the backslash after a keeps the leading spaces. The second inserts a comment before the server { line. The third appends a line after the last line ($) and saves the file.
Commands and addresses
| Command | Effect |
|---|---|
| sed '/re/a text' f | Add text after every matching line (GNU one-line form) |
| sed '/re/i text' f | Add text before every matching line |
| sed '3a text' f | After line 3 |
| sed '1i text' f | Before the first line (top of the file) |
| sed '$a text' f | After the last line |
| sed '/re/c text' f | Replace the matching line with text |
| sed '/re/r other.txt' f | Insert the contents of other.txt after each match |
| sed '0,/re/s//&\ntext/' f | Only after the first match (GNU, using s with a newline) |
| sed -i.bak '/re/a text' f | Same as the first row, saved in place with a backup |
Insert only after the first match
printf '%s\n' '[a]' 'x=1' '[a]' 'x=2' > dup.ini
sed '0,/^\[a\]/{/^\[a\]/a y=0
}' dup.iniOutput
[a] y=0 x=1 [a] x=2
The address 0,/re/ (GNU) ends at the first matching line, so the a command inside the braces runs once. Without it the line would be added after both [a] sections.
Portable form for macOS and BSD
BSD sed needs the text on the next line, after a backslash, and with -i a backup suffix argument:
sed -i '' '/listen 80;/a\
listen [::]:80;
' nginx.confThis multi-line form also works with GNU sed, which makes it the choice for scripts that run on both. The GNU one-liner on macOS fails with command a expects \ followed by text, and a typo in the command letter gives errors such as extra characters after command.
Check the result
Run the command without -i first and look at the output, or use -i.bak and compare with diff nginx.conf.bak nginx.conf. grep -n -A1 'listen 80;' nginx.conf shows that the new line is where you expected.
FAQ
How do I insert a line at the top of a file?
Address line 1 with the i command, sed -i '1i first line' file. On an empty file this inserts nothing, because sed never reads a line 1; use printf 'first line\n' > file in that case.
How do I add a line only if it is not already there?
sed cannot easily check the whole file first. Test with grep, grep -qxF 'line' file || echo 'line' >> file for the end of the file, or grep -qxF 'line' file || sed -i '/^anchor/a line' file after an anchor.
Why do the leading spaces of my inserted line disappear?
GNU sed strips the whitespace before the text in the one-line form. Start the text with a backslash to keep it, as in sed '/x/a\ indented' file.