AKA
AKA

Reputation: 6965

Extract data between delimiters from a Shell Script variable

I have this shell script variable, var. It keeps 3 entries separated by new line. From this variable var, I want to extract 2, and 0.078688. Just these two numbers.

var="USER_ID=2
     # 0.078688
     Suhas"

These are the code I tried:

echo "$var" | grep -o -P '(?<=\=).*(?=\n)' # For extracting 2

echo "$var" | awk -v FS="(# |\n)" '{print $2}' # For extracting 0.078688

None of the above working. What is the problem here? How to fix this ?

Upvotes: 2

Views: 1142

Answers (5)

OscarAkaElvis
OscarAkaElvis

Reputation: 5724

You can do it with pure bash using a regex:

#!/bin/bash

var="USER_ID=2
 # 0.078688
 Suhas"

[[ ${var} =~ =([0-9]+).*#[[:space:]]([0-9\.]+) ]] && result1="${BASH_REMATCH[1]}" && result2="${BASH_REMATCH[2]}"
echo "${result1}"
echo "${result2}"

Upvotes: 1

NeronLeVelu
NeronLeVelu

Reputation: 10039

Assuming this is the format of data as your sample

# For extracting 2
echo "$var" | sed -e '/.*=/!d' -e 's///'
echo "$var" | awk -F '=' 'NR==1{ print $2}'

# For extracting 0.078688
echo "$var" | sed -e '/.*#[[:blank:]]*/!d' -e 's///' 
echo "$var" | awk -F '#' 'NR==2{ print $2}'

Upvotes: 0

Zumo de Vidrio
Zumo de Vidrio

Reputation: 2121

With awk:

First value:

echo "$var" | grep 'USER_ID' | awk -F "=" '{print $2}'

Second value:

echo "$var" | grep '#' | awk '{print $2}'

Upvotes: 0

Inian
Inian

Reputation: 85895

Just use tr alone for retaining the numerical digits, the dot (.) and the white-space and remove everything else.

tr -cd '0-9. ' <<<"$var"
2      0.078688

From the man page, of tr for usage of -c, -d flags,

tr [OPTION]... SET1 [SET2]

-c, -C, --complement use the complement of SET1

-d, --delete delete characters in SET1, do not translate

To store it in variables,

IFS=' ' read -r var1 var2 < <(tr -cd '0-9. ' <<<"$var")
printf "%s\n" "$var1"
2
printf "%s\n" "$var2"
2
0.078688

Or in an array as

IFS=' ' read -ra numArray < <(tr -cd '0-9. ' <<<"$var")
printf "%s\n" "${numArray[@]}"
2
0.078688

Note:- The -cd flags in tr are POSIX compliant and will work on any systems that has tr installed.

Upvotes: 5

P....
P....

Reputation: 18411

echo "$var" |grep -oP 'USER_ID=\K.*'
2
echo "$var" |grep -oP '# \K.*'
0.078688

Your solution is near to perfect, you need to chance \n to $ which represent end of line.

echo "$var"  |awk -F'# ' '/#/{print $2}'
0.078688
echo "$var"  |awk -F'=' '/USER_ID/{print $2}'
2

Upvotes: 2

Related Questions