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.

Was it helpful?

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top