GobiasKoffi
GobiasKoffi

Reputation: 4084

Substring extraction using bash shell scripting and awk

So, I have a file called 'dummy' which contains the string:

"There is 100% packet loss at node 1".

I also have a small script that I want to use to grab the percentage from this file. The script is below.

result=`grep 'packet loss' dummy` |
awk '{  first=match($0,"[0-9]+%")
        last=match($0," packet loss")
        s=substr($0,first,last-first)
        print s}'

echo $result

I want the value of $result to basically be 100% in this case. But for some reason, it just prints out a blank string. Can anyone help me?

Upvotes: 2

Views: 17665

Answers (5)

Arvind Pai
Arvind Pai

Reputation: 31

You could do this with bash alone using expr.

i=`expr "There is 98.76% packet loss at node 1" : '[^0-9.]*\([0-9.]*%\)[^0-9.]*'`; echo $i;

This extracts the substring matching the regex within \( \).

Upvotes: 2

janks
janks

Reputation: 2158

Here I'm assuming that the output lines you're interested in adhere strictly to your example, with the percentage value being the only variation.

With that assumption, you really don't need anything more complicated than:

awk '/packet loss/ { print $3 }' dummy

This quite literally means "print the 3rd field of any lines containing 'packet loss' in them". By default awk treats whitespace as field delimiters, which is perfect for you.

If you are doing more than simply printing the percentage, you could save the results to a shell variable using backticks, or redirect the output to a file. But your sample code simply echoes the percentages to stdout, and then exits. The one-liner does the exact same thing. No need for backticks or $() or any other shell machinations whatsoever.

NB: In my experience, piping the output of grep to awk is usually doing something that awk can do all by itself.

Upvotes: 0

ghostdog74
ghostdog74

Reputation: 342263

the solution below can be used when you don't know where the percentage numbers are( and there's no need to use awk with greps)

$ results=$(awk '/packet loss/{for(i=1;i<=NF;i++)if($i~/[0-9]+%$/)print $i}' file)
$ echo $results
100%

Upvotes: 2

Dennis Williamson
Dennis Williamson

Reputation: 359875

You would need to put the closing backtick after the end of the awk command, but it's preferable to use $() instead:

result=$( grep 'packet loss' dummy |
awk '{  first=match($0,"[0-9]+%")
    last=match($0," packet loss")
    s=substr($0,first,last-first)
    print s}' )

echo $result

but you could just do:

result=$( grep 'packet loss' | grep -o "[0-9]\+%" )

Upvotes: 4

Steve Emmerson
Steve Emmerson

Reputation: 7832

Try

awk '{print $3}'

instead.

Upvotes: 3

Related Questions