1

I need to extract the integer value from some log files. The integer value always appears after a substring return code. But it may or may not have additional stuff after this substring. Below are two example entries:

Job with id 0 ended with status COMPLETED, return code 16, in 1 minute 12 seconds 
Job with id 0 COMPLETED with return code 255

So, here I want 16 in the first case, and 255 in the second case.

My initial approach was to use awk - but the column in which the required value occurs is not consistent; so it failed.

How do I achieve this in a reliable manner?

  • Yes, it will only appear once. The above two lines are the only way it can appear in these log files (I confirmed this by checking the program that writes this log line) – Bajal Mar 17 '16 at 17:14
  • And it's always code followed by some digits? Would Perl instead of shell scripting also be possible? – mnille Mar 17 '16 at 17:18
  • yes. code followed by digits. After the digits, there may or may not be content. perl is ok, I can collect the output into a variable in my bash script I think – Bajal Mar 17 '16 at 17:20
2

Use parameter expansion:

#! /bin/bash

strings=('Job with id 0 ended with status COMPLETED, return code 16, in 1 minute 12 seconds'
         'Job with id 0 COMPLETED with return code 255'
        )

for string in "${strings[@]}" ; do
    code=${string#*return code }
    code=${code%%[!0-9]*}
    echo $code
done

# removes pattern from the left, % from the right.

  • Thank you, this worked well for me as a pure bash solution. – Bajal Mar 17 '16 at 17:54
  • btw, I assume you meant to say * from the right (instead of %) – Bajal Mar 17 '16 at 17:55
  • @Bajal: Actually, no. * is a wildcard that matches anything. See Parameter Expansion in man bash. – choroba Mar 17 '16 at 17:56
  • Oh ok, I misunderstood. It is clear to me now. Thanks again. – Bajal Mar 17 '16 at 18:40
2

Using perl a solution using regexp could be:

perl -ne 'print "$2\n" if m/(code )(\d*)/' a.txt

This prints the numbers 16and 255 to stdout, each on a separate line (\n). Here a.txtcontains the two lines

Job with id 0 ended with status COMPLETED, return code 16, in 1 minute 12 seconds
Job with id 0 COMPLETED with return code 255
0

Here's a sed version:

sed -e 's/.*return code \([0-9]\+\).*/\1/' logfile.txt

It removes everything from the line except the digits immediately following return code.

or, using extended regexps with GNU sed:

sed -r -e 's/.*return code ([0-9]+).*/\1/' logfile.txt 

NOTE: some versions of sed use -E rather than -r to enable extended regular expressions.

Also note these sed scripts will print unchanged any lines that don't match the regular expression. If that's not what you want, use sed's -n option and the p command to print only matching lines, e.g.:

sed -n -r -e 's/.*return code ([0-9]+).*/\1/p' logfile.txt 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.