/commands/sed/sed-print-specific-lines
sed -n '10,20p' file: print specific lines or a line range
- 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
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.txtOutput
--- 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
| Command | Prints |
|---|---|
| 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
seq 1 1000000 > big.txt
sed -n '3,5p;5q' big.txtOutput
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.
Print a block between two patterns
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.
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.iniOutput
[server] port=2 host=a [log] --- line numbers of matches: 2 4
Equivalent commands
| Task | sed | Alternative |
|---|---|---|
| Line 5 | sed -n '5p;5q' file | awk 'NR==5 { print; exit }' file |
| Lines 10 to 20 | sed -n '10,20p;20q' file | head -n 20 file | tail -n 11 |
| First 10 lines | sed -n '1,10p' file or sed 10q file | head -n 10 file |
| Last line | sed -n '$p' file | tail -n 1 file |
| Line numbers of matches | sed -n '/error/=' file | grep -n error file |
Pitfalls
- Quote the script with single quotes. In double quotes the shell expands
$pto an (empty) variable, sosed -n "$p"runs an empty script and prints nothing. - Line numbers count across all input files:
sed -n '1p' a.txt b.txtprints only the first line ofa.txt. GNU sed's-streats 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.