Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Assume I have a text file as below

abcd
aaaaaaa
gfgk
hahahahahahhahh
gf

Then gf would be returned.Any good ideas?

share|improve this question

4 Answers 4

up vote 5 down vote accepted

Assuming your lines each contain a 'word' of characters,
and, we don't mind letting the shell do a little more work,
Here is a AWK solution.

# Let your text be in `str.txt`

awk '{print length($1), $1}' str.txt | sort -nk 1 | head -1

# Output: 2 gf ## Which is the shortest string

You can optimize this to avoid a sort with some more AWK.
You can tweak this further if you have more than one 'word' per line.

Also note that if you have multiple shortest strings, this will give you one of them.
You can do some more tricks to get them too.

share|improve this answer
    
I like this but it should use $0 (full line) instead of $1 (first field). $1 will only return up to the first whitespace. SpawnST's example doesn't have any spaces, so either would work if his real data file is the same. –  Doug Harris Apr 29 '10 at 3:11
    
@Doug, I refer you to the opening sentence of the answer :-) –  nik Apr 29 '10 at 13:44
    
Oops, sorry I missed your assumption line. I had already given your answer an upvote anyway. –  Doug Harris Apr 29 '10 at 14:09

Awk is great for this:

awk '(NR == 1 || length < length(shortest)) { shortest = $0 } END { print shortest }'

The first part sets the "shortest" variable to the current line if it is the first line or if the length is shorter than the shortest line seen previously. Finally, the last part prints out the value of shortest.

share|improve this answer
    
Awesome, added to the tool box. –  l0b0 Mar 9 '11 at 13:31

BASH FAQ entry #1 tells how to read a file line by line. ${#foo} will give you the length of $foo. Just loop, testing each line in turn.

share|improve this answer

A solution using sed, and keeping the 1st shortest line from the file:

sed -e '1h;H;g;s/[^\n]/#/g;s/\(#*\)\n\1/\n/;G;/^\n/s/\n.*\n\(.*\)\n.*/\1/;s/.*\n//;h;$!d' your_file

To keep the last shortest line from the file:

sed -e '1h;G;h;s/[^\n]/#/g;s/\(#*\)\n\1/\n/;G;/^\n/s/\n.*\n\(.*\)\n.*/\1/;s/.*\n//;h;$!d' your_file

Bellow is an explained version of the 1st shortest line in the form of a sed script file that can be run using sed -f script your_file:

# The hold space will contain the shortest line at the beginning and the ending of each cycle.
# The 1st line is the shortest, so put it in the hold space so an empty line will not be returned.
1h
# Append the current line to the shortest so far, remember these 2 lines in the hold space, and take a copy in the pattern space to work on them.
H;g
# Replace all chars by #.
s/[^\n]/#/g
# Delete the same number of # before and after the line delimiter.
s/\(#*\)\n\1/\n/
# Append the 2 lines remembered in the hold space to the pattern space.
G
# If the hold space begin by a '\n', the current line was shorter, so keep it.
/^\n/s/\n.*\n\(.*\)\n.*/\1/
# Else, the previous line was shorter, so keep it.
s/.*\n//
# Remember shortest in hold space.
h
# If last line, print it (delete everything else).
$!d
share|improve this answer
    
+1 for if you look very closely and long enough at this sed script, you can see the woman in the red dress... –  michael_n Jun 19 '13 at 6:43

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.