简体   繁体   中英

Sed Capture Group Regex

I have the following string as output

Config(1) = ( value1:4000 value2:2000 value3:500 value4:1000)

I want to capture all 4 values into 4 different variables in bash and I think the cleanest way to do that is with regex. And I think the best way to use regex for this is with sed. I have tested the regex and can capture the value1 with

value1:(\d+)

With sed I am trying this based on other answers:

echo "Config(1) = ( value1:4000 value2:2000 value3:500 value4:1000)" | sed -n 's/^\s*value1\:\(\d\+\)\s\?.*/\1/p'

This returns nothing

BASH supports regular expressions natively:

#!/bin/bash

s='Config(1) = ( value1:4000 value2:2000 value3:500 value4:1000)'
pattern='value1:([0-9]+) value2:([0-9]+) value3:([0-9]+) value4:([0-9]+)'

if [[ "$s" =~ $pattern ]]
then
        echo "${BASH_REMATCH[1]}"
        echo "${BASH_REMATCH[2]}"
        echo "${BASH_REMATCH[3]}"
        echo "${BASH_REMATCH[4]}"
fi
4000
2000
500
1000

You could grep for the value with the -o flag to only output the match.

This outputs 4000

echo "Config(1) = ( value1:4000 value2:2000 value3:500 value4:1000)" | grep -Po '(?<=value1:)\d+'

Though it's tough to advise about if its the cleanest way to achieve your goal without more context, a program (in awk maybe?) that parses that output format might be interesting here.

This will work Create a simple two statement script

var=`echo "Config(1) = ( value1:4000 value2:2000 value3:500 value4:1000)" | grep -Eo "\( .*\)"|sed 's/^.\(.*\).$/\1/'`
for v in $var; do
 echo $v| awk -F: '{print $2}'
done

Run as

root@114855-T480:/home/yadav22ji# ./tpr
4000
2000
500
1000

You can assign these values to variables as you said.

Could you please try following, it will match all string values in Input_file and will create an array out of its values.

readarray -t arr < <\
(awk '
{
  while(match($0,/value[0-9]+:[0-9]+/)){
    val=substr($0,RSTART,RLENGTH)
    sub(/value[0-9]+:/,"",val)
    print val
    $0=substr($0,RSTART+RLENGTH)
  }
}' file
)

Above will create an array named arr you want to access its values then try:

echo "${arr[@]}"

Parsing and capturing every value to the variable:

result=`echo "Config(1) = ( value1:4000 value2:2000 value3:500 value4:1000)"`
declare -A variables=( ["variableone"]="1" ["variabletwo"]="2" ["variablethree"]="3" ["variablefour"]="4" )
for index in ${!variables[*]}
do
    export $index=$(echo $result | tr ' ' '\n' | sed "s/[()]//g" |  grep value | awk -F ":" '{print $2}' | head -"${variables[$index]}" | tail -1)
done

Array item- name of the variable

Array index - counter line using in head command


[root@centos ~]# env | grep variable
variablefour=1000
variableone=4000
variabletwo=2000
variablethree=500

I think following regex could be more shorter form in @hmm answer

value[0-9]{1}:([0-9]+)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM