leo
leo

Reputation: 59

How to select a string from a variable using grep or awk

I have a variable which has content like

----- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------------------------------|---------|----------|---------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- All files | 36.95 | 20.87 | 24.

PS: The output I mentioned is actually pretty long and I trimmed it for the sake of posting here. I found out by trial and error that All files <> | was between position 970-990

I am trying to extract the value associated with All files i.e 36.95. I am able to use cut to get the substring like this

TOTAL="$(cut -c 975-990 <<< $RES)"

But I am looking for better approach for example using a regex pattern, I saw patterns like grep and awk but I am not able to formulate it.

Upvotes: 1

Views: 191

Answers (4)

Ed Morton
Ed Morton

Reputation: 204731

I don't believe your RES variable contents are all on 1 line, I think you're making it look that way by using echo $RES instead of echo "$RES" and what it really contains looks more like:

$ echo "$RES"
----------
  File    | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|------------------
All files |  36.95  |   20.87  | 24.

in which case all you need is:

$ echo "$RES" | awk -F' *[|] *' '/All files/{print $2}'
36.95

Upvotes: 1

kvantour
kvantour

Reputation: 26591

Since RES is a shell variable, you could do something like this:

TOTAL="${RES#*All Files}"
TOTAL="${TOTAL#*|}"
TOTAL="${TOTAL%|*}"
TOTAL="${TOTAL// /}"
  • The first line removes everything up to and including the words All Files
  • Since it is unsure how many spaces are after the words All Files, we remove again everything upto the first <pipe>-character
  • Finally, we remove everything after the first <pipe>-character.
  • As a final step, we delete all spaces

Upvotes: 1

Erwin
Erwin

Reputation: 952

If you're not limiting yourself to cut, this is a possible answer using sed that looks for the All files | ... | pattern and grabs the text from there.

TOTAL="$(sed -E 's/^.* All files \| ([^ ]+) \| .*$/\1/' <<< $RES)"

Here's a tiny script with that idea put to use:

#!/bin/bash

RES="----- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------------------------------|---------|----------|---------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- All files | 36.95 | 20.87 | 24."
TOTAL="$(sed -E 's/^.* All files \| ([^ ]+) \| .*$/\1/' <<< $RES)"
echo "$TOTAL"

Running that:

$ ./test.sh
36.95

Upvotes: 1

tink
tink

Reputation: 15248

And since you mentioned it - here an awk alternative:

total=$(awk -F'|' '{print $12}'<<<"${res}")

Note: all uppercase variable names are (more by convention than anything) reserved for the system.

Upvotes: 2

Related Questions