Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm looking for the simplest method to print the longest line in a file. I did some googling and surprisingly couldn't seem to find an answer. I frequently print the length of the longest line in a file, but I don't know how to actually print the longest line. Can anyone provide a solution to print the longest line in a file? Thanks in advance.

share|improve this question
1  
What about when there are multiple "longest" lines?. Because you want more than a simple maximum length, do you want to see all instances of lines which are equal longest? –  Peter.O Nov 13 '11 at 14:20
add comment

7 Answers

up vote 12 down vote accepted
cat ./text | awk ' { if ( length > x ) { x = length; y = $0 } }END{ print y }'

UPD: summarizing all the advices in the comments

awk 'length > max_length { max_length = length; longest_line = $0 } END { print longest_line }' ./text 
share|improve this answer
12  
Useless Use of cat. awk '{ if ( length > x ) { x = length; y = $0 } }END{ print y }' text –  Keith Thompson Nov 13 '11 at 1:37
3  
It is, both calling another command (cat), and using a pipe are expensive operations, not to mention that it's more efficient for awk to just read the file. The performance implications are definitely noticeable if this is done frequently, and even so, you are completely misusing cat. –  Chris Down Nov 13 '11 at 2:37
4  
The slightly shorter and more idiomatic: awk 'length > x { x = length; y = $0 } END { print y }'. Nothing wrong with your answer, dimitry, just presenting an alternative to help people understand awk a little better. –  camh Nov 13 '11 at 5:10
4  
@dmitry.malikov Do what I do; every time somebody points out a UUOC in my answer I add another one on. cat ./text | cat - | awk ' { if ( length > x ) { x = length; y = $0 } }END{ print y }' –  Michael Mrozek Nov 13 '11 at 5:41
6  
@Michael Mrozek - there's a reason it's considered useless, and your reply is childish and representative of your stubbornness to listen to reason. There is no reason to use cat with awk, grep, sed, etc., since they can all natively handle files directly. –  laebshade Nov 13 '11 at 16:22
show 11 more comments
sed -rn "/.{$(<file expand -t1 |wc -L)}/{p;q}" file

This first reads the file inside the command substitution and outputs the length of the longest line, (previously, expand converts tabs to spaces, to overcome the semantics of wc -L -- each tab in the line will add 8 instead of 1 to line length). This length is then used in a sed expression meaning "find a line this number of characters long, print it, then quit". So this actually can be as optimal as the longest line is near to the top of the file, heheh (thanks fered for the awesome and constructive comments).

Another, I had thought earlier than the sed one (in bash):

#!/bin/bash
while read -r line; do
    (( ${#line} > max )) && max=${#line} && longest="$line"
done
echo "$longest"
share|improve this answer
2  
This method is very expensive and slow. –  Chris Down Nov 13 '11 at 2:47
2  
@Chris Down: Oh yes it is. But the question was about the sortest method, not the most efficient. WOrks finely for small to medium files or non critical tasks, though. –  ata Nov 13 '11 at 11:49
3  
WARNING: wc's option -L, --max-line-length prints the length of the longest line, according to the man page, but if you dig deeper (as in when you get wrong / unexpected results), you find that this option increments the length by 8 for each 1 tab char \x09 see this Unix & Linux Q/A –  Peter.O Nov 13 '11 at 13:05
    
PS. Your answer will print all the "equally longest" lines, which is probably a good thing... To force wc to count only 1 char per tab, this works. sed -rn "/.{$(<file expand -t1 |wc -L)}/p" file –  Peter.O Nov 13 '11 at 14:13
1  
read line will interpret backslash-escaped chars as the literal char, eg \A resloves to A, which of course effectively reports a shorter than actual byte-usage... To prevent this escaped interpretation, use: read -r line . . . . Also, to make the sed+wc version quit after the first "longest line", change p to {p;q} .. sed -rn "/.{$(<file expand -t1 |wc -L)}/{p;q}" file –  Peter.O Nov 14 '11 at 3:15
show 3 more comments

In pure bash:

#!/bin/bash

_max_length=0
while IFS= read -r _line; do
    _length="${#_line}"
    if (( _length > _max_length )); then
        _max_length=${_length}
        _max_line=( "${_line}" )
    elif (( _length == _max_length )); then
        _max_line+=( "${_line}" )
    fi
done

printf 'Max line length: %d\n' "${_max_length}"
printf 'Lines matched with that length: %d\n' "${#_max_line[@]}"
(( ${#_max_line[@]} )) && printf '%s\n' '----------------' "${_max_line[@]}"
share|improve this answer
    
As-is, the code can return invalid results. Setting _max_line[0]=${_line} does not remove the rest of any previously accumulated shorter "longest lines"... unset _max_line will clear the entire array... –  Peter.O Nov 13 '11 at 21:00
    
@fered Thanks for that, was written pretty quickly. Fixed. –  Chris Down Nov 13 '11 at 21:03
add comment

The following example was going to be, and should have been, a comment to dmitry.malikov's answer, but because of the Useless Use of Visible Comment Space there, I've chosen to present it here, where it will at least be seen...

This is a simple variation of the dmitry's single-pass awk method.
It prints all "equal longest" lines. (Note. delete array is a gawk extension).

awk 'length >x { delete y; x=length }
     length==x { y[NR]=$0 } END{ for (z in y) print y[z] }' file
share|improve this answer
add comment

Here's a Perl solution:

perl -e 'while(<>){
           $l=length;  
           $l>$m && do {$c=$_; $m=$l}  
         } print $c' file.txt 

Or, if you want to print all the longest lines

perl -e 'while(<>){
           $l=length;
           push @{$k{$l}},$_;
           $m=$l if $l>$m;
         } print @{$k{$m}}' file.txt 

Since I had nothing better to do, I ran some benchmarks on a 625M text file. Surprisingly, my Perl solution was consistently faster than the others. Granted, the difference with the accepted awk solution is tiny, but it is there. Obviously, solutions that print multiple lines are slower so I have sorted by type, fastest to slowest.

Print only one of the longest lines:

$ time perl -e 'while(<>){
           $l=length;  
           $l>$m && do {$c=$_; $m=$l}  
         } print $c' file.txt 
real    0m3.837s
user    0m3.724s
sys     0m0.096s



$ time awk 'length > max_length { max_length = length; longest_line = $0 }
 END { print longest_line }' file.txt
real    0m5.835s
user    0m5.604s
sys     0m0.204s



$ time sed -rn "/.{$(<file.txt expand -t1 |wc -L)}/{p;q}" file.txt 
real    2m37.348s
user    2m39.990s
sys     0m1.868s

Print all longest lines :

$ time perl -e 'while(<>){
           $l=length;
           push @{$k{$l}},$_;
           $m=$l if $l>$m;
         } print @{$k{$m}}' file.txt 
real    0m9.263s
user    0m8.417s
sys     0m0.760s


$ time awk 'length >x { delete y; x=length }
     length==x { y[NR]=$0 } END{ for (z in y) print y[z] }' file.txt
real    0m10.220s
user    0m9.925s
sys     0m0.252s


## This is Chris Down's bash solution
$ time ./a.sh < file.txt 
Max line length: 254
Lines matched with that length: 2
real    8m36.975s
user    8m17.495s
sys     0m17.153s
share|improve this answer
add comment
cat filename | awk '{ print length }' | sort -n | tail -1
share|improve this answer
add comment

You can use wc:

wc -L fileName
share|improve this answer
3  
Please read the question again. The required output is the longest line itself, not the length of the longest line. Also see Peter.O's comment regarding wc -L's drawback. –  manatwork May 1 '13 at 11:47
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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