Skip to content

/commands/sed/sed-print-specific-lines

sed -n '10,20p' file: print specific lines or a line range

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
os
linux, macos, windows

sed -n '10,20p' file prints lines 10 to 20 of a file, and sed -n '5p' file prints only line 5. The -n option turns off sed's default of printing every line, and the p command prints the lines selected by the address. For a large file, add a quit command so sed stops reading after the last line you need: sed -n '10,20p;20q' file.

Examples

bash
seq 1 30 > numbers.txt
echo '--- line 5'
sed -n '5p' numbers.txt
echo '--- lines 10-13'
sed -n '10,13p' numbers.txt
echo '--- last line'
sed -n '$p' numbers.txt
echo '--- lines 3 and 7'
sed -n '3p;7p' numbers.txt
echo '--- every 10th line (GNU first~step)'
sed -n '0~10p' numbers.txt

Output

--- line 5
5
--- lines 10-13
10
11
12
13
--- last line
30
--- lines 3 and 7
3
7
--- every 10th line (GNU first~step)
10
20
30

Addresses you can use

CommandPrints
sed -n '5p'Line 5
sed -n '10,20p'Lines 10 to 20
sed -n '25,$p'From line 25 to the end
sed -n '$p'The last line
sed -n '/start/,/end/p'From the first line matching start to the next line matching end
sed -n '10,+4p'Line 10 and the 4 lines after it (GNU)
sed -n '1~2p'Odd lines: first~step (GNU)
sed '10,20d'Everything except lines 10 to 20

Stop early on large files

bash
seq 1 1000000 > big.txt
sed -n '3,5p;5q' big.txt

Output

3
4
5

Without 5q, sed reads the remaining lines of the file before exiting. The equivalent with other tools is head -n 20 file | tail -n 11 or awk 'NR>=10 && NR<=20' file.

A range address can use regular expressions on both ends, which is the usual way to cut one section out of a config file or a log. Both boundary lines are included. Use = to print line numbers when you need to know where the block is.

bash
printf '[client]\nport=1\n[server]\nport=2\nhost=a\n[log]\nlevel=3\n' > app.ini
sed -n '/^\[server\]/,/^\[log\]/p' app.ini
echo '--- line numbers of matches:'
sed -n '/port=/=' app.ini

Output

[server]
port=2
host=a
[log]
--- line numbers of matches:
2
4

Equivalent commands

TasksedAlternative
Line 5sed -n '5p;5q' fileawk 'NR==5 { print; exit }' file
Lines 10 to 20sed -n '10,20p;20q' filehead -n 20 file | tail -n 11
First 10 linessed -n '1,10p' file or sed 10q filehead -n 10 file
Last linesed -n '$p' filetail -n 1 file
Line numbers of matchessed -n '/error/=' filegrep -n error file

Pitfalls

  • Quote the script with single quotes. In double quotes the shell expands $p to an (empty) variable, so sed -n "$p" runs an empty script and prints nothing.
  • Line numbers count across all input files: sed -n '1p' a.txt b.txt prints only the first line of a.txt. GNU sed's -s treats each file separately.
  • If the end of a range is a smaller line number than the start (sed -n '20,10p'), only line 20 is printed.
  • If a regex range never finds its end pattern, sed prints to the end of the file.

FAQ

Why does sed '5p' print the whole file?

sed prints every line by default, and p prints the selected line once more. Add -n to turn off the default output so only the addressed lines appear.

How do I print a line whose number is in a shell variable?

Use double quotes so the shell expands the variable, for example sed -n "${n}p" file or sed -n "${start},${end}p" file. Keep $ for the last line escaped or in single quotes, because the shell would expand it too.

Is sed faster than head and tail for a line range?

With a q command both stop reading at the last line needed, so the difference is small. Without q, sed reads the rest of the file, which matters on multi-gigabyte logs.

Sources