1

I have a data in a file as {{1,department}}.

I need to capture the values as given below:

val1=1
val2=department

I tried awk command for data with single {}, it worked. but for double {{}} the command is not working.

the command i used is:

`var1=`echo $line | awk -F '[{}]' '{print $2}' | awk -F '[,]' '{print $1}'

3 Answers 3

4

With GNU grep and any POSIX shell:

out=$(grep -Po '\{\{\K.*?(?=\}\})' < your-file)
val1=${out%%,*}
val2=${out#*,}
  • -P: tells grep to use perl compatible regular expressions for it's \K and (?=) operators
  • \K: sets the start of the returned value. a\Kb matches on ab but returns b. So here, we match on {{... but only return ... to exclude {{ from the output.
  • (?=...) achieves the same thing for }}. It's a look-ahead operator that matches with 0 width if ... matches there without ... being included in the returned value
  • so $out ends up with 1,department. We use the ${var%%pattern} and ${var#pattern} standard shell operators to extract the part before and after the first comma.

That assumes the file contains only one {{...}} occurrence and that it contains at least one comma.

POSIXly, you can replace that grep command with:

sed -n 's/.*{{\([^}]*\)}}.*/\1/p'

Now if you have

some text {{1,department}} other text

in a shell variable, you can also extract it with:

  • zsh

    if [[ $string =~ '\{\{([^},]*),([^}]*)\}\}' ]]; then
      val1=$match[1] val2=$match[2]
    fi
    
  • bash

    if [[ $string =~ \{\{([^},]*),([^}]*)\}\} ]]; then
      val1=${BASH_REMATCH[1]} val2=${BASH_REMATCH[2]}
    fi
    
2
  • can u explain me this.. also i m having line in a variable.. not in a file. say $line. How will i use command for same
    – akr
    Aug 1, 2018 at 6:13
  • i have the file with many {{}} with each occurring on different line. So i m reading each line in a loop as $ line and processing each further. So how to use the same command on a variable
    – akr
    Aug 1, 2018 at 6:24
2
$ echo "{{1,department}}" | awk -F "{{|}}|," '{print $3}'
department

$ echo "{{1,department}}" | awk -F "{{|}}|," '{print $2}'
1
2
  • can u explain it pls..
    – akr
    Aug 1, 2018 at 6:25
  • 1
    we have three seperators. 1. {{ 2.}} 3. ,(comma). based upon that, we are printing the values. so {{ is taken as one separator.
    – Kamaraj
    Aug 1, 2018 at 6:37
1

You can print the values (with a leading space) with:

$ echo "{{1,department}}" | awk -F '[ {},]' 'NF=NF'
 1 department

That will allow to read the values:

read val1 val2 <<<$(echo "{{1,department}}" | awk -F '[ {},]' 'NF=NF')

This will work for one bracket and any additional fields:

$ echo "{{1,department,name,list}}" | awk -F '[ {},]' 'NF=NF'
 1 department name list

A similar solution is possible with grep:

$ echo '{1,department}' | grep -Po '(?<={|,)[^{,}]*(?=,|})'
1
department

$ echo '{{1,department}}' | grep -Po '(?<={|,)[^{,}]*(?=,|})'
1
department

$ echo '{{1,department,name,list}}' | grep -Po '(?<={|,)[^{,}]*(?=,|})'
1
department
name
list

From a variable in the shell it needs to match the exact number of fields:

$ value='{{1,department}}'
$ re='\{\{([^},]*),([^}]*)\}\}'
$ [[ $value =~ $re ]] && echo "${BASH_REMATCH[@]:1}"
1 department
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .