Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

HELP SORTING A FILE

Status
Not open for further replies.

johngiggs

Technical User
Oct 30, 2002
492
0
0
US
If I have a file with multiple lines and I want to sort it in reverse order by the number of login failures, how would I go about doing such when the Login Fails field is sometimes the 4th field and sometimes the 5th field?

Username Name Login Fails Flags Last Login
USER1 Joe Schmoe 1 DisPwdHis 30-OCT-2002
FTP Dennis A. Johnson 50 DisPwdHis 16-JAN-2003

I know that if they were all in the 4th field, then I could do a cat filename | sort -nr -k 4,4 | awk '{print $1, $2, $3, $4, $5, $6}'

How would I go about doing this if the field I want to sort by could be either the 4th or 5th field depending on the user's name.

Any help would be greatly appreciated.

Thanks,

John
 
Hi John,
you can try to do this using temporary file.
step #1
cat filename |&
while read -p ln
do
set `echo $ln`
if [ $# -eq 6 ] ; then
echo "$6 $5 $1 $2 $3 $4" >> tmpfile
else
echo "$5 $4 $1 $2 $3" >> tmpfile
fi
done

step #2
sort file tmpfile using fields 1 and 2

step #3
like step #1, but "back on front"

Regards Boris

 
The following is an example of how you could do this in Perl. It assumes that the distinctive feature of the login failures field is that is is the first occurence on the line of the pattern 'whitespace-numbers-whitespace':
Code:
#!/usr/bin/perl -w
chomp(@lines = <>);
@lines = map { $_->[0] }
         sort { $a->[1] <=> $b->[1] }
         map { [ $_, ($_ =~ /\s+(\d+)\s+/) ] }
         @lines;
$&quot; = &quot;\n&quot;;
print &quot;@lines\n&quot;;
It looks fairly complicated, but here is my attempt to explain what is happening:
The first line reads in all the lines either from standard input, or a file (or files) specified as arguments to the file. After reading in the lines, newline characters are removed from each line using 'chomp'.
Now the complicated bit. Reading from the bottom of the second expression, the array @lines is passed to a map expression. The map expression constructs an anonymous array where element 0 is the current line, and element 1 is the failures number. So we now have an array of anonymous 2 element arrays. This array of arrays is now sorted according to a numeric comparison of element 1 of each anonymous array (the failures field). And finally, element 1 of the anonymous array is discarded to leave element 0, which is the original line, now in sorted order.
We then print the contents of @lines, first by specifying the list separator $&quot; to be the newline character, then printing the array.
Could be a little complex for your situation, but have a play :)
 
Hi John,

It looks like your input is seperated by tabs. If so, you could do something like

awk ' FS=&quot;<TAB>&quot; {print $3,$4,$5,$1,$2}' filename |sort -nr -k 1

Replace <TAB> by a TAB character...
Of course your output will change slightly :)

Willem
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top