/flags/coreutils/tail-n-plus-skip-lines
tail -n +2: print a file starting at line N (skip a header)
- 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
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,2nOutput
--- 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
Related counts
| Command | Prints |
|---|---|
| tail -n 5 | The last 5 lines (the default is 10) |
| tail -n +5 | From line 5 to the end |
| head -n 5 | The first 5 lines |
| head -n -5 | Everything except the last 5 lines (GNU only) |
| tail -c +100 | From byte 100 to the end |
| sed -n 5,10p | Lines 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.
seq 1 12 > numbers.txt
tail -n +5 numbers.txt | head -n 6 | tr '\n' ' '; echo
head -n -9 numbers.txt | tr '\n' ' '; echoOutput
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:
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.
+Nis the first line printed, so skipping two header lines istail -n +3, not+2. - Several files. With more than one file, tail prints
==> name <==headers and applies+Nto each file; add-qto suppress the headers, or useawk '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 +Nsplit multibyte UTF-8 characters if N falls inside one. - Follow mode.
tail -n +1 -f logprints the whole file and then keeps following it, useful when a log is short but must be watched. - On macOS, BSD
tail -n +Nworks the same way; onlyhead -n -Nis 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.