LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   bash get larger numerical match from 2 lines (https://www.linuxquestions.org/questions/programming-9/bash-get-larger-numerical-match-from-2-lines-4175597164/)

bishop2001 01-10-2017 10:36 AM

bash get larger numerical match from 2 lines
 
greetings. i have output which looks like the following:

Jan 10 joe 2017 10:15:10 something for 2 but not from 3 pcs
Jan 10 joe 2017 10:15:10 something for 2 but not from 4 pcs
Jan 10 joe 2017 10:15:10 something for 2 but not from 1 pcs

I would like to just print the line which has the higher value based on the 12th column which is the '4' in this example Suggestions please ?

Thanks again,

grail 01-10-2017 10:55 AM

awk

dlb101010 01-10-2017 11:15 AM

Hey bishop2001,

You could try:
Code:

cat data.txt | sort -nrk12 | head -n 1
(or use <your command> rather than 'cat data.txt' if that's how you're generating the info)

HTH,
Dave

danielbmartin 01-10-2017 12:29 PM

With this InFile ...
Code:

Jan 10 joe 2017 10:15:10 something for 2 but not from 3 pcs
Jan 10 joe 2017 10:15:10 something for 2 but not from 4 pcs
Jan 10 joe 2017 10:15:10 something for 2 but not from 1 pcs

... this code ...
Code:

sort -rk12,1 <$InFile  \
|head -1              \
>$OutFile

... produced this OutFile ...
Code:

Jan 10 joe 2017 10:15:10 something for 2 but not from 4 pcs
... but using the same InFile this awk ...
Code:

awk '{if ($12>best) best=$0}  \
  END{print best}' $InFile >$OutFile

... produced this OutFile ...
Code:

Jan 10 joe 2017 10:15:10 something for 2 but not from 3 pcs
Please correct my error.

Daniel B. Martin

Turbocapitalist 01-10-2017 12:35 PM

Quote:

Originally Posted by danielbmartin (Post 5652982)
Code:

awk '{if ($12>best) best=$0}  \
  END{print best}' $InFile >$OutFile



Code:

awk '{if ($12>best) { best=$12; bestline=$0 } }  \
  END{print bestline}' $InFile >$OutFile


danielbmartin 01-10-2017 12:52 PM

Quote:

Originally Posted by Turbocapitalist (Post 5652986)
Code:

awk '{if ($12>best) { best=$12; bestline=$0 } }  \
  END{print bestline}' $InFile >$OutFile


Excellent. Thank you.

Daniel B. Martin

grail 01-10-2017 12:55 PM

As pointed out, having the variable for the test and the storage is not the correct way to go.
Alternative awk (just for fun):
Code:

awk '{a[$12]=$0}END{print a[b[asorti(a,b)]]}' file
Would have been nice to seen an effort from the OP before everyone started to give solutions ;)

danielbmartin 01-10-2017 02:29 PM

Quote:

Originally Posted by grail (Post 5652991)
Code:

awk '{a[$12]=$0}END{print a[b[asorti(a,b)]]}' file

Short and sweet! Love it!

{LQ won't let me rep you again, darnit.}

Daniel B. Martin

danielbmartin 01-10-2017 02:32 PM

Quote:

Originally Posted by grail (Post 5652991)
Would have been nice to seen an effort from the OP before everyone started to give solutions ;)

If OP was asking for a solution in bash and only bash, then nobody has yet answered his question.

Daniel B. Martin

astrogeek 01-10-2017 05:08 PM

Quote:

Originally Posted by danielbmartin (Post 5653042)
If OP was asking for a solution in bash and only bash, then nobody has yet answered his question.

Daniel B. Martin

No need to spoil the fun! ;)

Here is one with bash only:

Code:

#!/bin/bash
while read line; do
        num=${line%% pcs}
        num=${num##*from }
        [ 0${num} -gt 0${maxnum} ] && maxnum=$num && maxline=$line
done
echo $maxline


grail 01-11-2017 12:21 AM

More bash :)
Code:

#!/usr/bin/env bash

while read -ra line
do
  (( ${line[-2]} > keep )) && keep=${line[-2]} && kline="${line[@]}"
done<file

echo "$kline"


astrogeek 01-11-2017 12:48 AM

Very nice grail!

And agreed, it would be nice to see the OP participate!

pan64 01-11-2017 01:08 AM

Quote:

Originally Posted by grail (Post 5652991)
Alternative awk (just for fun):
Code:

awk '{a[$12]=$0}END{print a[b[asorti(a,b)]]}' file

My god, how did you find this?

By the way, in post #4 the variable best and in post #10 maxnum and in post #11 keep were not initialised, which in this case is ok, but in general it may cause misbehaviour. The usual way is to use the first data line to start with.

grail 01-11-2017 03:13 AM

Quote:

Originally Posted by pan64 (Post 5653211)
My god, how did you find this?

By the way, in post #4 the variable best and in post #10 maxnum and in post #11 keep were not initialised, which in this case is ok, but in general it may cause misbehaviour. The usual way is to use the first data line to start with.

Just the way my brain works :) I did initially do the longer version with the sort separate and then just wondered if I could include it ... which you can :D

I do follow what you mean about initialising, but normally only worry in languages where it is a gotcha, like ruby :(

danielbmartin 01-11-2017 09:37 PM

Several solutions have been posted, and they fall into two categories: some use a sort, others use a single pass through the data. If the input file is large (thousands of lines) intuition suggests that "single pass" should be preferred because it will run in less time.

Right? Wrong? Opinions?

Daniel B. Martin


All times are GMT -5. The time now is 10:29 PM.