Sorting lines from longest to shortest [duplicate]
Asked Answered
S

4

29

How can I rearrange all of the lines in a file from longest to shortest? For e.g.:

elephant
zoo
penguin

Would be changed to

elephant
penguin
zoo
Sami answered 28/11, 2011 at 13:41 Comment(1)
The example is a bit misleading, if you don't go back to read the question. To sort list of words, longest to shortest, adapt the acceptable answer e.g. pip search json |awk '{print length($1)"\t"$1}' |sort -rn |cut -d' ' -f2-. Obviously "pip search json" is just there to produce output instead of a filename.Impaction
O
57

Add the line length as the first field of the line, sort, and remove the line length:

awk '{ print length($0) " " $0; }' $file | sort -r -n | cut -d ' ' -f 2-
Oratorio answered 28/11, 2011 at 13:42 Comment(6)
why the cat? UUoCAMultilingual
@Fredrik: I like to have the filename in front of my pipelines. You have the nicer award, though, so I have fixed it.Oratorio
can be shortened to $ awk '{print length"\t"$0}' File | sort -rn | cut -f2- which is basically the same thing except that cut operates on tabs per default so ignore this :-)Multilingual
@Fredrik Your shorter version that uses tabs as delimiter instead of the space character has the negative side effect that the tab is printed first. Command $ awk '{print length"\t"$0}' tlds-alpha-by-domain.txt outputs ` "$0}' tlds-alpha-by-domain.txt2 AC`etc... Using the longer version without tabs generates safer terminal/command output. At least when running in bash version 3.2 on Mac OS X 10.7.5.Homily
@thiton: You can put the filename at the front without using cat, like this: < input_file command1 | command2 | commmand3 > output_fileArticulation
I'm using the similar way to find the first build.gradle by using: find $PWD -name "build.gradle" | awk '{print length($0), $0 | "sort -n"}' | head -1 | cut -d ' ' -f 2-Paunch
A
4

TIM (my terse version for TIMTOWTDI... hmm but now it's long already :(

perl -ne '@a = <>; print sort { length $b <=> length $a } @a' file

lets reserve reverse and push when needed

and I wonder how long it would take on that 550MB file

Alainealair answered 11/8, 2016 at 14:45 Comment(1)
The 550MB file took 14.2 seconds on perl 5.24Gerrit
G
2

Perl version, with a tip of the hat to @thiton:

perl -ne 'print length($_)." $_"' file | sort -r -n | cut -d ' ' -f 2-

$_ is the current line, similar to awk's $0

perl-5.24 execution on a 550MB .txt file with 6 million lines (British National Corpus) took 24 seconds


@thiton's awk (3.1.7) execution took 26 seconds


With a tip of the hat to @William Pursell from a related post:

perl -ne 'push @a, $_; END{ print reverse sort { length $a <=> length $b } @a }' file

perl-5.24 execution took 12.0 seconds

Gerrit answered 4/11, 2015 at 0:23 Comment(0)
S
1

With POSIX Awk:

{
  c = length
  m[c] = m[c] ? m[c] RS $0 : $0
} END {
  for (c in m) q[++x] = m[c]
  while (x) print q[x--]
}

Example

Surplice answered 2/7, 2012 at 4:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.