Skip to content

/flags/coreutils/tail-n-plus-skip-lines

tail -n +2: print a file starting at line N (skip a header)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · ls (GNU coreutils) 8.32updated
tool
GNU coreutils
command
tail
flag
-n +NUM
default
-n 10 (the last 10 lines)

tail -n +2 file prints the file starting from line 2, so it drops exactly the first line: the usual way to strip a CSV header before sorting or counting. The plus sign changes the meaning of the number. tail -n 2 counts from the end and prints the last two lines; tail -n +2 counts from the beginning and prints from line 2 onward. tail -n +1 prints the whole file.

With and without the plus sign

bash
printf 'id,score\n1,40\n2,75\n3,60\n' > scores.csv
echo '--- tail -n 2 (last two lines)'
tail -n 2 scores.csv
echo '--- tail -n +2 (from line 2)'
tail -n +2 scores.csv
echo '--- header removed, then sorted'
tail -n +2 scores.csv | sort -t, -k2,2n

Output

--- tail -n 2 (last two lines)
2,75
3,60
--- tail -n +2 (from line 2)
1,40
2,75
3,60
--- header removed, then sorted
1,40
3,60
2,75
CommandPrints
tail -n 5The last 5 lines (the default is 10)
tail -n +5From line 5 to the end
head -n 5The first 5 lines
head -n -5Everything except the last 5 lines (GNU only)
tail -c +100From byte 100 to the end
sed -n 5,10pLines 5 to 10

Combining both directions gives a line range: tail -n +5 file | head -n 6 prints lines 5 to 10, the same as sed -n '5,10p', shown in sed -n: print specific lines.

bash
seq 1 12 > numbers.txt
tail -n +5 numbers.txt | head -n 6 | tr '\n' ' '; echo
head -n -9 numbers.txt | tr '\n' ' '; echo

Output

5 6 7 8 9 10
1 2 3

Keep the header and process the rest

To sort data but keep the header line on top, print the header with head -n 1 and the body with tail -n +2:

bash
printf 'id,score\n1,40\n2,75\n3,60\n' > scores.csv
{ head -n 1 scores.csv; tail -n +2 scores.csv | sort -t, -k2,2nr; }

Output

id,score
2,75
3,60
1,40

Pitfalls

  • Off by one. +N is the first line printed, so skipping two header lines is tail -n +3, not +2.
  • Several files. With more than one file, tail prints ==> name <== headers and applies +N to each file; add -q to suppress the headers, or use awk 'FNR > 1' to skip the first line of each file.
  • Obsolete syntax. Old scripts use tail +2. POSIX dropped it, so prefer -n +2.
  • Byte counts with -c +N split multibyte UTF-8 characters if N falls inside one.
  • Follow mode. tail -n +1 -f log prints the whole file and then keeps following it, useful when a log is short but must be watched.
  • On macOS, BSD tail -n +N works the same way; only head -n -N is GNU-specific.

FAQ

What is the difference between tail -n 2 and tail -n +2?

tail -n 2 prints the last two lines. tail -n +2 prints everything from line 2 to the end, which drops only the first line. The plus sign switches the count from lines counted from the end to the line number where output starts.

How do I remove the last line of a file instead?

Use GNU head with a negative count, head -n -1 file, which prints all lines except the last one. macOS head does not accept negative counts; use sed '$d' there.

Can I still write tail +2 without -n?

GNU tail accepts the obsolete form tail +2 when only one file is given, but POSIX removed it and other implementations may reject it. Write tail -n +2, which works on every current system.

Sources