3
\$\begingroup\$

Do you think the way I'm doing it is fine? Is this the most typical way to do it? Share your thoughts please.

# Display the last three lines of a text file with line numbers in reverse order
# Can come quite in handy when reading log file entries
cat -n [FILE] | tac | head --lines=3

Test:

# Let's create a text file to test our command against
cat > test.txt

# Copy and paste these lines into the terminal window and press Ctrl+D to let
# the shell know that we're done entering our stuff
house
car
boy
cat
lake
sea
laptop
rain

# Run the command
cat -n test.txt | tac | head --lines=3

# Brief description:
# cat -n test.txt | - Pipe the output with line numbers to the tac command
# tac |             - Reverse the order and pipe along to the head command
# head --lines=3    - Display only the first three lines

# Output:
     8  rain
     7  laptop
     6  sea

# The number next to the first line in our output (8  rain) should be equal to
# the number of lines in the entire file. We can check that using the word count
# utility:
wc -l test.txt

# Output (It's 8 too. Looks like the test passes):
8 test.txt
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

cat -n is kind of an anti pattern. The cat command is for displaying the content, adding line numbering is a violation of the single responsibility principle.

tac is not portable. Although it's quite common in Linux, not so much in UNIX and osx.

Instead of head --lines=3 it's more common to use the shorter form head -n 3.

I don't quite get why you would want to see the last n lines reversed. If reversing is not important, then a portable alternative to print the last n lines with line numbers could be using awk and tail:

awk '{ print NR ":" $0 }' file | tail -n 3

You could write the whole thing in Awk, and also reverse the lines. It will be longer to write, but portable, and solved in a single process rather than a pipeline of multiple commands.

\$\endgroup\$
2
  • \$\begingroup\$ All points duly noted. Thank you. So, I guess the best, as well as most portable, way to implement that would be like this: awk '{print NR ": " $0}' [FILE] | tail -N (where FILE is your file and N is the number of lines to output) \$\endgroup\$
    – misha
    Commented Mar 14, 2016 at 23:59
  • \$\begingroup\$ Yes, if you don't mind that the ordering of lines is not reversed \$\endgroup\$
    – janos
    Commented Mar 15, 2016 at 5:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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