How Do I Pull Info from String
-
01-10-2019 - |
Question
I am trying to pull dynamics from a load that I run using bash. I have gotten to a point where I get the string I want, now from this I want to pull certain information that can vary. The string that gets returned is as follows:
Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0
Each of the number can and will vary in length, but the overall structure will remain the same. What I want to do is be able to get these numbers and load them into some bash variables ie:
RECORDS=??
DELETED=??
SKIPPED=??
WARNING=??
In regex I would do it like this:
Records: (\d*?) Deleted: (\d*?) Skipped (\d*?) Warnings (\d*?)
and use the 4 groups in my variables.
Solution
You can use regex matching in Bash versions >= 3.2:
[[ $line =~ ([[:digit:]]+).*([[:digit:]]+).*([[:digit:]]+).*([[:digit:]]+) ]]
RECORDS=${BASH_REMATCH[1]}
DELETED=${BASH_REMATCH[2]}
SKIPPED=${BASH_REMATCH[3]}
WARNING=${BASH_REMATCH[4]}
OTHER TIPS
Built-in read
command will do the trick:
read TMP1 RECORDS TMP2 DELETED TMP3 SKIPPED TMP4 WARNING
Update: You can also use set
:
set $line
RECORDS=$2
DELETED=$4
SKIPPED=$6
WARNING=$8
Here's a shell function you can use that just creates a number of name/value pairs. It assumes things are formatted as you said, but is easy to change:
parseline() {
while [ $# -ge 2 ] ; do
eval $(echo $1 | tr -d : | tr '[a-z]' '[A-Z]')="$2"
shift 2
done
}
Execute it like:
$ parseline Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0
$ echo $RECORDS
2910
$ echo $WARNINGS
0
You can try something with 'sed' or 'cut' depending on the structure of the line like this:
#!/bin/sh
DYNAMIC="Records: 2910 Deleted: 1 Skipped: 2 Warnings: 3"
RECORDS=`echo "$DYNAMIC" | sed 's/.*Records: \([0-9]*\).*/\1/g'`
DELETED=`echo "$DYNAMIC" | sed 's/.*Deleted: \([0-9]*\).*/\1/g'`
SKIPPED=`echo "$DYNAMIC" | sed 's/.*Skipped: \([0-9]*\).*/\1/g'`
WARNINGS=`echo "$DYNAMIC" | sed 's/.*Warnings: \([0-9]*\).*/\1/g'`
echo "Records $RECORDS"
echo "Deleted $DELETED"
echo "Skipped $SKIPPED"
echo "Warnings $WARNINGS"
echo "$DYNAMIC" | cut -d " " -f2
echo "$DYNAMIC" | cut -d " " -f4
echo "$DYNAMIC" | cut -d " " -f6
echo "$DYNAMIC" | cut -d " " -f8
#!/bin/bash
s="Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0"
s=${s//: /=}
for i in $(printf ${s// /"\n"})
do
eval $i
done
echo "Records: $Records"
echo "Deleted: $Deleted"
echo "Skipped: $Skipped"
echo "Warnings: $Warnings"
output
$ ./shell.sh
Records: 2910
Deleted: 0
Skipped: 0
Warnings: 0