serah
serah

Reputation: 2147

grep for a condition and print another value in the string

how do I grep and print the transactions number that follows the word 'transaction' in the below lines, for the condition that the time a transaction takes is between 2-3 minutes? The below time is in milliseconds. Would help additionally if I can print the file name along with the match.

Time taken to process transaction 2599500398 is 1000 ms
Time taken to process transaction 2599500398 is 450640 ms
Time taken to process transaction 2599500398 is 638244 ms

Upvotes: 2

Views: 222

Answers (3)

Timur Shtatland
Timur Shtatland

Reputation: 12465

Use this Perl one-liner:

perl -lne 'my ( $tid, $time ) = /transaction\s+(\d+)\s+is\s+(\d+)\s+ms/; 2000 <= $time and $time <= 3000 and print "$ARGV: $tid";' in_file(s)

The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-n : Loop over the input one line at a time, assigning it to $_ by default.
-l : Strip the input line separator ("\n" on *NIX by default) before executing the code in-line, and append it when printing.

\d+ : Any digit, repeated 1 or more times.
\s+ : Any whitespace character, repeated 1 or more times.
$ARGV : Current input file name.

SEE ALSO:
perldoc perlrun: how to execute the Perl interpreter: command line switches

Upvotes: 1

Andy Lester
Andy Lester

Reputation: 93805

Don't use grep, because you are wanting to do math on the value you're getting back. When you say "between 2-3 minutes" you really mean "where ms is between 120000 and 239999 ms", and grep doesn't understand numeric values. It only understands patterns of strings. Some people will try to make tricksy regexes to get around this, but don't be lured down that path of sorrow.

Just do this:

 awk '/Time taken to process transaction/ && ($8 >= 120000) && ($8 < 240000) { print "Trx", $6, "took", $8, "ms" }' times.txt

That won't print any in your example because all your times are outside of the numeric range.

Upvotes: 1

Raman Sailopal
Raman Sailopal

Reputation: 12917

Using awk:

awk '{ if (($8*0.001)/60>=2 && ($8*0.001)/60<=3) { print $6" - "FILENAME } }' *.files

Check if the 8th, space delimited field converted to minutes is greater or equal to 2 and less than or equal to 3 and print the sixth space delimited field (transaction) along with the file name which is tracked by awk's built in FILENAME variable.

Upvotes: 2

Related Questions