×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Display consumer/service line with smallest time value

Display consumer/service line with smallest time value

Display consumer/service line with smallest time value

(OP)
Hello All,

I have a file with three fields delimited by a comma:
field1 is a consumer name
field2 is the service used by a given consumer
filed3 is a time value

I would like to display the line for each consumer/service pair with the earlier time i.e. smallest time value

Sample input file:

CODE

$ cat data
arx-count-consumer,arx-count-service,300
arx-count-consumer,arx-count-service,500
peg-if-consumer,peg-if-service,1100
tin-mock-consumer,tin-mock-service,1500
arx-count-consumer,arx-count-service,101
tin-mock-consumer,tin-mock-service,4500
pipe-mock-consumer,pipe-mock-service,50
pipe1-mock-consumer,pipe-mock-service,510 

Desired output:

CODE

arx-count-consumer,arx-count-service,101
peg-if-consumer,peg-if-service,1100
tin-mock-consumer,tin-mock-service,500
pipe-mock-consumer,pipe-mock-service,50
pipe1-mock-consumer,pipe-mock-service,510 

Any assistance would be greatly appreciated. Thanks in advance.

RE: Display consumer/service line with smallest time value

for storĂ­ng minimum values, you can use an associative array, e.g. min_time_values[key] where key would be a string concatenated from consumer and service.

Then for every line from your file, you could do:
- if array element min_time_values[key] does not exist yet, then create it by setting min_time_values[key] = time_value

- if array element min_time_values[key] already exist and when time_value is less than min_time_values[key] then change it by setting min_time_values[key] = time_value

RE: Display consumer/service line with smallest time value

By the way, with data you provided the result for tin-mock-consumer,tin-mock-service coud not be
tin-mock-consumer,tin-mock-service,500
but
tin-mock-consumer,tin-mock-service,1500

RE: Display consumer/service line with smallest time value

You can post the code what have you tried so far and where you got stuck

RE: Display consumer/service line with smallest time value

(OP)
Many thanks for your assistance Mikrom. Great approach to the problem.

CODE

$ cat get_min_time.awk
BEGIN { FS="," }
{
        key=sprintf("%s_%s", $1, $2)
        if(!min_time_value[key]) {
                min_time_value[key] = $3
        }

        if(min_time_value[key] > $3) {
                min_time_value[key]=$3
        }
}

END {
        for (i in min_time_value) {
          printf("%s,%s\n", i, min_time_value[i])
        }
} 

CODE

$ awk -f get_min_time.awk data
peg-if-consumer_peg-if-service,1100
pipe-mock-consumer_pipe-mock-service,50
tin-mock-consumer_tin-mock-service,1500
pipe1-mock-consumer_pipe-mock-service,510
arx-count-consumer_arx-count-service,101 

RE: Display consumer/service line with smallest time value

Yes, I would have done the same.
Maybe a small improvement: at the end you can use the split() function to restore the original values of consumer name and service:

CODE

...
END {
        for (i in min_time_value) {
          split(i, keys, "_")
          consumer = keys[1]
          service = keys[2]
          printf("%s,%s,%s\n", consumer, service, min_time_value[i])
        }
} 
Output:

CODE

peg-if-consumer,peg-if-service,1100
pipe-mock-consumer,pipe-mock-service,50
tin-mock-consumer,tin-mock-service,1500
pipe1-mock-consumer,pipe-mock-service,510 
arx-count-consumer,arx-count-service,101 

RE: Display consumer/service line with smallest time value

(OP)
Thank you Mikrom for your excellent advice.

RE: Display consumer/service line with smallest time value

(OP)
If there was a further field with a token value, is there an easy method to retrieve the entire line? I am interested in the token associated with the consumer/service pair with the smallest time value. For brevity, I have supplied a subset of data.

CODE

$1 consumer
$2 service
$3 token value
$4 time value

$ cat data
arx-count-consumer,arx-count-service,1234567890abcde,300
arx-count-consumer,arx-count-service,1234567890abcdf,500
arx-count-consumer,arx-count-service,1234567890abcdg,101

Desired output:
arx-count-consumer,arx-count-service,1234567890abcdg,101 

Any advice would be greatly appreciated.

RE: Display consumer/service line with smallest time value

entire line in awk is: $0

RE: Display consumer/service line with smallest time value

(OP)
Sorry, my description of the new requirement was poorly explained. The new objective it to get the consumer/service pair with the lowest time value ($4) and associated token ($3).

I have the correct result however I have done so via accidentally introducing a typo. Is someone able to explain why the below line works:

CODE

min_time_value[key] = $0 # $0 is a typo but it works. $4 is the correct field to use i.e time 

Is there is a better method for my required purpose?

CODE

$ cat get_min_time2.data
arx-count-consumer,arx-count-service,AF1001,300
arx-count-consumer,arx-count-service,DF7001,500
peg-if-consumer,peg-if-service,WS9000,1100
tin-mock-consumer,tin-mock-service,YU8000,1500
arx-count-consumer,arx-count-service,YP8000,101
tin-mock-consumer,tin-mock-service,RR5030,4500
pipe-mock-consumer,pipe-mock-service,ZP1020,50
pipe1-mock-consumer,pipe-mock-service,PL9090,510 

CODE

$ cat get_min_time2.awk

BEGIN { FS="," }
{
        key=sprintf("%s_%s", $1, $2)
        if(!min_time_value[key]) {				
                min_time_value[key] = $0 # $0 is a typo but it works. $4 is the correct field to use i.e time
        }

        if(min_time_value[key] > $4) {
                min_time_value[key]=$4
                token_value[key]=$3
        }
}

END {
        for (i in min_time_value) {
          if(i in token_value) {
            token=sprintf("%s", token_value[i])
          }
          split(i, keys, "_")
          consumer = keys[1]
          service = keys[2]
          printf("%s,%s,%s,%s\n", consumer, service, token, min_time_value[i])
        }
} 

CODE

$ awk -f get_min_time2.awk get_min_time2.data
peg-if-consumer,peg-if-service,WS9000,1100
pipe-mock-consumer,pipe-mock-service,ZP1020,50
tin-mock-consumer,tin-mock-service,YU8000,1500
pipe1-mock-consumer,pipe-mock-service,PL9090,510
arx-count-consumer,arx-count-service,YP8000,101 

RE: Display consumer/service line with smallest time value

i think, that it is because always applies $0 > $4 (lexicographical string comparision) so your program executes every time the body of the second if

CODE

if(min_time_value[key] > $4) {
                min_time_value[key]=$4
                token_value[key]=$3
        } 

RE: Display consumer/service line with smallest time value

to print entire lines i would do something like this:

CODE

BEGIN {
  FS = ","
}

{ 
  consumer = $1
  service = $2
  time_value = $4
  key = consumer"#"service
  if (!min_time_values[key]) { 
    min_time_values[key] = time_value
    line[key] = $0
  }
  else {
    if (time_value < min_time_values[key]) {
      min_time_values[key] = time_value
      line[key] = $0
    }
  }
}

END {
  for (key in min_time_values) {
      print line[key]
  }
} 

Output:

CODE

$ cat marm1.txt
arx-count-consumer,arx-count-service,1234567890abcde,300
arx-count-consumer,arx-count-service,1234567890abcdf,500
arx-count-consumer,arx-count-service,1234567890abcdg,101

$ awk -f marm1.awk marm1.txt
arx-count-consumer,arx-count-service,1234567890abcdg,101 

RE: Display consumer/service line with smallest time value

(OP)
Thank you mikrom.
Your solution is a clean and simpler approach to the problem posed.
A big thank you once again - excellent coding.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login


Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close