head

Show the first part of a file

Updated 2026-08-23

head prints the first 10 lines of each file it is given, or of standard input. -n changes the count and -c counts bytes instead of lines.

A negative count inverts the job: head -n -5 prints everything except the last 5 lines, which drops a trailer without needing to know how long the file is.

In a pipeline head exits as soon as it has its lines, closing the pipe and sending SIGPIPE to whatever was writing, so grep error huge.log | head -3 stops searching once three matches exist. That saving does not apply to a command which must consume all its input before producing any, of which sort is the obvious one.

tail is the other end of the same file, and the two compose: head -n15 report.txt | tail -n3 gives lines 13 to 15.

Sample files used on this page

Every example below was run against these files. Recreate them to follow along.

report.txt 40 numbered lines, each 5 words

line 1 of the report
line 2 of the report
line 3 of the report

line 40 of the report

users.csv a header row plus 6 records

name,age,department
Alice,34,Engineering
Bob,29,Sales
Carol,41,Engineering
Dave,25,Marketing
Erin,38,Sales
Frank,31,Engineering

access.log 10 requests in the standard combined log format

203.0.113.5 - - [13/Aug/2026:09:12:01] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:12:03] "GET /style.css HTTP/1.1" 200 231
198.51.100.7 - - [13/Aug/2026:09:14:22] "GET /index.html HTTP/1.1" 200 512
198.51.100.7 - - [13/Aug/2026:09:14:25] "GET /missing.html HTTP/1.1" 404 162
203.0.113.5 - - [13/Aug/2026:09:15:47] "GET /index.html HTTP/1.1" 200 512
192.0.2.44 - - [13/Aug/2026:09:16:03] "POST /login HTTP/1.1" 302 0
192.0.2.44 - - [13/Aug/2026:09:16:04] "GET /dashboard HTTP/1.1" 200 4021
198.51.100.7 - - [13/Aug/2026:09:18:51] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:19:10] "GET /api/status HTTP/1.1" 500 89
192.0.2.44 - - [13/Aug/2026:09:20:33] "GET /dashboard HTTP/1.1" 200 4021

bytes.txt ten bytes, no trailing newline, so the -c examples have something exact to cut

abcdefghij
31 outputs, collapsed by default

The first N lines

With no flags at all, head prints 10 lines.

Show the first 10 lines of a file

head report.txt

The default count, and the reason head file is a habit for looking at something unfamiliar.

Show output
line 1 of the report
line 2 of the report
line 3 of the report
line 4 of the report
line 5 of the report
line 6 of the report
line 7 of the report
line 8 of the report
line 9 of the report
line 10 of the report

Show the first 5 lines

head -n 5 report.txt

-n takes the count. This is the portable spelling, and the one to write in a script.

Show output
line 1 of the report
line 2 of the report
line 3 of the report
line 4 of the report
line 5 of the report

Use the older shorthand for the same thing

head -5 report.txt

-5 means -n 5. Obsolescent in POSIX terms, universally supported in practice, and shorter to type at a prompt.

Show output
line 1 of the report
line 2 of the report
line 3 of the report
line 4 of the report
line 5 of the report

Show just the first line

head -n1 report.txt

head -n1 is how you read a header row, a shebang line, or the first line of a generated file.

Show output
line 1 of the report

Read a CSV header and the first records

head -n 3 users.csv

Enough to see the column names and confirm the delimiter before writing anything that parses the file.

Show output
name,age,department
Alice,34,Engineering
Bob,29,Sales

Take the first lines of a pipeline

sort access.log | head -3

With no filename, head reads standard input. Note that sort has to read all of its input before it can emit any, so this stops head early without saving sort any work.

Show output
192.0.2.44 - - [13/Aug/2026:09:16:03] "POST /login HTTP/1.1" 302 0
192.0.2.44 - - [13/Aug/2026:09:16:04] "GET /dashboard HTTP/1.1" 200 4021
192.0.2.44 - - [13/Aug/2026:09:20:33] "GET /dashboard HTTP/1.1" 200 4021

Cut a long search short

grep 200 access.log | head -2

Here the early exit does save work: head closes the pipe once it has two lines, and grep stops searching rather than reading to the end of the file.

Show output
203.0.113.5 - - [13/Aug/2026:09:12:01] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:12:03] "GET /style.css HTTP/1.1" 200 231

Take the first lines of literal text

printf 'one\ntwo\nthree\nfour\n' | head -2

Useful when testing what a pipeline will do to a small sample before pointing it at a real file.

Show output
one
two

Ask for nothing and get nothing

head -n 0 report.txt; echo "(nothing)"

-n 0 is valid and prints no lines at all. Worth knowing when the count comes from a variable that might be zero.

Show output
(nothing)

Write the first lines to a new file

head -n3 report.txt > first3.txt && cat first3.txt

head prints to standard output like anything else, so the shell's > does the writing. The cat is only here to show the result.

Show output
line 1 of the report
line 2 of the report
line 3 of the report

Several files at once

Given more than one file, head labels each with a ==> filename <== header and separates them with a blank line.

Read the top of two files together

head -n3 report.txt users.csv

The headers are what make the combined output readable. They appear whenever there is more than one file.

Show output
==> report.txt <==
line 1 of the report
line 2 of the report
line 3 of the report

==> users.csv <==
name,age,department
Alice,34,Engineering
Bob,29,Sales

Read the top of three files

head -n2 report.txt users.csv access.log

The pattern holds for any number of files, which makes head -n2 *.conf a quick way to see what a directory of config files starts with.

Show output
==> report.txt <==
line 1 of the report
line 2 of the report

==> users.csv <==
name,age,department
Alice,34,Engineering

==> access.log <==
203.0.113.5 - - [13/Aug/2026:09:12:01] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:12:03] "GET /style.css HTTP/1.1" 200 231

Suppress the headers

head -q -n2 report.txt users.csv

-q concatenates the results with nothing between them, which is what you want when the output is going into another command rather than to a person.

Show output
line 1 of the report
line 2 of the report
name,age,department
Alice,34,Engineering

Force a header for a single file

head -v -n2 report.txt

-v prints the header even when there is only one file, so a loop over filenames produces consistently labelled output.

Show output
==> report.txt <==
line 1 of the report
line 2 of the report

See what happens when one file is missing

head -n2 report.txt nosuchfile.txt; echo "exit: $?"

head reads the files it can, reports the one it cannot on standard error, and exits 1. A script checking the status will see the failure even though it also got real output.

Show output
==> report.txt <==
line 1 of the report
line 2 of the report
head: cannot open 'nosuchfile.txt' for reading: No such file or directory
exit: 1

Read a file that is not there at all

head nosuchfile.txt; echo "exit: $?"

The same error and status with nothing to print alongside it.

Show output
head: cannot open 'nosuchfile.txt' for reading: No such file or directory
exit: 1

Bytes instead of lines

-c counts bytes, and stops mid-line without hesitation. On UTF-8 text that can cut a character in half, so it suits binary files and fixed-width records rather than prose.

Show the first N bytes

head -c 20 report.txt

Exactly 20 bytes, which here happens to land on a line boundary because each line is 20 characters plus its newline.

Show output
line 1 of the report

Take the whole file by byte count

head -c 10 bytes.txt

Asking for exactly the file's length gives the whole thing, and asking for more does the same rather than failing.

Show output
abcdefghij

Combine -n and -c

head -n 2 -c 8 report.txt

They do not add up: whichever limit is reached first wins, and -c given last takes precedence over -n.

Show output
line 1 o

Everything except the last N

A negative count inverts the job. head -n -5 prints the whole file apart from its final 5 lines, which is how to drop a trailer whose length you know when the file's length you do not.

Drop the last N lines

head -n -35 report.txt

40 lines minus the last 35 leaves the first 5. Nothing here needed to know the file was 40 lines long.

Show output
line 1 of the report
line 2 of the report
line 3 of the report
line 4 of the report
line 5 of the report

Drop just the final line

head -n -1 users.csv

The everyday form: strip a summary row, a trailing marker, or the last record of a file being processed in batches.

Show output
name,age,department
Alice,34,Engineering
Bob,29,Sales
Carol,41,Engineering
Dave,25,Marketing
Erin,38,Sales

Drop trailing bytes

head -c -5 bytes.txt; echo

The byte form works the same way, taking everything but the final 5 bytes.

Show output
abcde

Everyday patterns

Where head turns up in real pipelines, usually alongside something that produced more output than anyone wants to read.

Pull a slice out of the middle of a file

head -n15 report.txt | tail -n3

First 15 lines, then the last 3 of those, giving lines 13 to 15. tail approaches the same file from the other end.

Show output
line 13 of the report
line 14 of the report
line 15 of the report

Read the records after a header

tail -n +2 users.csv | head -3

tail -n +2 starts at line 2, dropping the header, and head -3 keeps the first three records after it.

Show output
Alice,34,Engineering
Bob,29,Sales
Carol,41,Engineering

Read only the header

head -1 users.csv

The column names on their own, which is what you want before deciding which field number to cut.

Show output
name,age,department

Sample a column from the top of a log

head -n5 access.log | cut -d' ' -f1

cut takes field 1 from the first five requests. Enough to see the shape of the data without processing the whole file.

Show output
203.0.113.5
203.0.113.5
198.51.100.7
198.51.100.7
203.0.113.5

Count what head actually returned

head -n2 report.txt | wc -l

Worth doing when the count comes from elsewhere: head gives you fewer lines than asked for without complaint if the file is shorter.

Show output
2