Skip to content

/commands/sed/sed-insert-line-after-match

sed insert a line after or before a matching line (a and i commands)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · sed (GNU sed) 4.9updated
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

bash
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.conf

Output

server {
    listen 80;
    listen [::]:80;
    server_name example.test;
}
===
# managed by deploy script
server {
    listen 80;
    server_name example.test;
}
===
}
# end of file

The 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

CommandEffect
sed '/re/a text' fAdd text after every matching line (GNU one-line form)
sed '/re/i text' fAdd text before every matching line
sed '3a text' fAfter line 3
sed '1i text' fBefore the first line (top of the file)
sed '$a text' fAfter the last line
sed '/re/c text' fReplace the matching line with text
sed '/re/r other.txt' fInsert the contents of other.txt after each match
sed '0,/re/s//&\ntext/' fOnly after the first match (GNU, using s with a newline)
sed -i.bak '/re/a text' fSame as the first row, saved in place with a backup

Insert only after the first match

bash
printf '%s\n' '[a]' 'x=1' '[a]' 'x=2' > dup.ini
sed '0,/^\[a\]/{/^\[a\]/a y=0
}' dup.ini

Output

[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:

bash
sed -i '' '/listen 80;/a\
    listen [::]:80;
' nginx.conf

This 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.

Sources