0

This is the output from the file I'm using:

aaaaa
bbbbb
ccccc
ddddd
eeeee
fffff
ggggg
hhhhh
iiiii
jjjjj

I know using tail -n 5 filename will display this:

fffff
ggggg
hhhhh
iiiii
jjjjj

How do I use the head command in such a way to display the same exact lines?

head -n 10 filename | tail -n 5 filename works, but that's just redundant for what I'm looking for.

  • Do you mean the last five lines, or lines 6-10? – Mikel Apr 4 '18 at 15:30
  • Why do you want to use only head? Why do you think head can do this? – Mikel Apr 4 '18 at 15:31
  • Your question isn't clear. You want to display the line numbers? Or you want to use head to show the same lines that tail did? – Otheus Apr 4 '18 at 15:35
  • @Otheus My bad, I'm looking for the latter. I want head to print out the same exact lines as tail did. – Morgan C. Apr 4 '18 at 15:38
  • Using head to print the tail of a file instead of using tail is nonsensical at best. It may nor be clear with a small file like in your example, but what if the file is 50MiB of text? Do you still want lines 6-10, or do you want the last 5 lines in the file? – Mioriin Apr 4 '18 at 17:24
2

Your command

head -n 10 filename | tail -n 5 filename

is nonsensical. The output of head will never be read by tail as tail is already reading directly from filename. Therefore, the result is exactly the same as with just

tail -n 5 filename

The head utility is used to get a certain number of lines from the top of the file (or, with GNU head, all lines of the file except for a certain number of lines counting from the end of the file). The head utility is not what you want to use to get the tail end of a file's data. For that, use tail as you have shown.

Any other solution would be more complex than your basic tail -n 5.

For example:

tac filename | head -n 5 | tac

which assumes that one has tac from GNU coreutils installed. Both head and tail will be installed on any system that has an even remotely POSIX compliant shell environment, while tac will only be found on Linux systems and other systems where GNU coreutils has been installed.

Or, you could implement your own tail in awk if it's tail that you just don't want to use:

$ awk -vn=5 '{ lines[i++ % n] = $0 } END { for (j = 0; j < n; ++j) print lines[(i+j)%n] }' filename
fffff
ggggg
hhhhh
iiiii
jjjjj
0

I think, this is what you want.

foo@bar~$ cat file 
aaaaa
bbbbb
ccccc
ddddd
eeeee
fffff
ggggg
hhhhh
iiiii
jjjjj

You want to use head to print out the same exact lines as tail did.

foo@bar~$ tail -n 5 file 
fffff
ggggg
hhhhh
iiiii
jjjjj

Solution

foo@bar~$ sort -r file | head -5 | sort
fffff
ggggg
hhhhh
iiiii
jjjjj
  • tac file | head -5 | tac also does the same job – Dipankar Nalui Apr 4 '18 at 17:29
0

This implementation uses head without tail to display only the last 5 lines of the file.

head -n -0 filename | sed 1,$(echo "$(wc -l filename | awk '{ print $1 }')-5" | bc -l)d

head -n -0 filename -- Displays all the lines in the file.

From man head:

-n, --lines=[-]N print the first N lines instead of the first 10; with the leading ‘-’, print all but the last N lines of each file

$(echo "$(wc -l filename | awk '{ print $1 }')-5" | bc -l) -- Calculates the number of lines to delete based on the total number of lines in the file minus 5.

sed 1,(NUMBER_OF_LINES_TO_DELETE)d -- Removes all but the last 5 lines based on the previous calculation.

-1

head is for getting the first n lines of a file. tail is for getting the last n lines of a file. If you want something more general-purpose, you can check out this thread.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.