Shell Tricks: Quick line numbering

[Tweet : ADN : nvALT]

It’s often useful to quickly see line numbers when viewing source code files. The less command and related tools can display with line numbers. There’s also the nl command, but it doesn’t number blank lines and tends to mess up formatting. There’s are ways that are more flexible and better looking. Enter grep and paste.

grep version

If you pass a “match everything” pattern to grep (.*) and include the -n flag, you’ll get the entire file passed back with line numbers followed by colons.

A quick alias makes this easily accessible:

alias grepno="grep --color=never -n -E '.*'"

Now you can just type grepno [filename.txt] to see numbered output.

$ grepno Rakefile
[...]
46:Rake.application.options.trace = false
47:verbose(false)
48:run_time = Time.now

The nice thing about the -n switch is that you can actually search with it and see the resulting line numbers for just the matching lines. Same with ack, ag (Silver Searcher), and others.

I don’t love the output, though.

paste version

The paste command has a somewhat esoteric function:

The paste utility concatenates the corresponding lines of the given input files, replacing all but the last file’s newline characters with a single tab character, and writes the resulting lines to standard output.

For this tip, we’re overriding the newline-to-tab conversion (with the -d flag) and replacing newlines with TAB-newline, maintaining the newline but indenting it. sed = will number the lines in the output, and the -s switch on paste will restore our whitespace keeping the line number justified to the left.

# output a text file with line numbers
lno() {
    if [ $# == 0 ]; then
        echo "No filename provided."
    else
        sed = "$1" | paste -s -d '\t\n' - -
    fi
}

This will give you nicely formatted, line-numbered output.

$ lno Rakefile
[...]
46  Rake.application.options.trace = false
47  verbose(false)
48  run_time = Time.now

You can pass it to less for (in my opinion) better-looking output than less’s default -n switch. You can also pipe it to grep to filter, generating the same paginated output as grep -n with better formatting. You can also redirect to a file (> output.txt) or the clipboard (| pbcopy) for line-numbered text you can share.

Ryan Irelan has produced a series of shell trick videos based on BrettTerpstra.com posts. Readers can get 10% off using the coupon code TERPSTRA.