TransWikia.com

how to capture parameter and value from line

Unix & Linux Asked on December 24, 2021

we want to capture only the parameter – segment.bytes and his value

example

echo "$info" | grep "segment.bytes"
{"version":1,"config":{"segment.bytes":"10737555","retention.bytes":"104857600"}}

what I think is to drop all the words until segment.bytes and cut the segment.bytes include the value without the double Quotes

example of expected results

echo "$info" | grep "segment.bytes" |  ......

segment.bytes:10737555

I try this

echo "$info" | grep "segment.bytes"   | sed s'/"/ /g' |  sed 's/^.*segment.bytes/segment.bytes/' | awk '{print $1":"$3}

and I get

segment.bytes:10737555

but I feel my approach could be dangerous , since the results to get the value is very sensitive and important , get wrong results could be catastrophic

I will happy to get other option that are more reliable

4 Answers

You can below awk command

echo "$info"|awk -F "," '/segment.bytes/{for(i=1;i<=NF;i++){if($i ~ /segment/){gsub(""","",$i);print $i }}}'| sed "s/.*{//g"

output

segment.bytes:10737555

Answered by Praveen Kumar BS on December 24, 2021

The safe and robust way to go here is the jq utility:

$ echo "$info" 
| grep -F  '"segment.bytes"' 
| jq  -r '.config | "segment.bytes:" +  ."segment.bytes"' 

bash:

Employing parameter substitutions we clip from left and right ends and extract the value of the segment.bytes attribute.

name="segment.bytes"
var=${info#*"${name}":"}
printf "%s:%sn" "$name"  "${var%%"*}"'

Another way to do it is, first carve up tye info string into newlines on comma and braces, so that grep can then be brought to bear and strip the double quotes from grep's output:

$ echo "$info" 
| tr '{,}' '[n*]' 
| grep '^"segment.bytes"' 
| tr -d "

Using Perl with the JSON module

$ echo "$line" | grep -F  '"segment.bytes"' 
| perl -MJSON -lne '$,=":";
  my $k = "segment.bytes";
  print $k, decode_json($_)->{config}{$k};
'

In case JSON module is unavailable you can do this also. Here in this we first generate a valid Perl code using sed and then bring it to life in perl by means of the do statement. Then the json object $j is a hash reference from which we extract the keys we want.

$ echo "$info" 
| sed  
    -e '/"segmen.bytes"/!d'  
    -e 'y/:/,/;s/.*/$j=&;/' 
  > ./foo.json 
$ perl -I. -le '$,=":";
  my $name = "segment.bytes";
  do "foo.json" or die $!;
  print $name, $j->{config}{$name};
'

The awk and sed are pretty self explanatory

$ echo "$info" | grep -F segment.bytes 
| awk -F '"segment\.bytes":"'  '
  {
    t = $2
    sub(/".*/, "", t)
    $0 = FS t
    gsub(/["\]/, "")
  }1'
$ echo "$info" | grep -F segment.bytes 
| sed -ne '
    y/{,}/nnn/
    /^"segment.bytes"/!D
    s/"//g;P
  ' 

Answered by Rakesh Sharma on December 24, 2021

You don't need to call grep before calling sed.

$ echo "$info"
foo
{"version":1,"config":{"segment.bytes":"10737555","retention.bytes":"104857600"}}
bar

$ echo "$info" | sed -n 's/.*"(segment.bytes)":"([^"]*)".*/1:2/p'
segment.bytes:10737555

or for a very specific match on that whole line to make the odds of a false match close to impossible but would obviously be more sensitive to changes in the format of the input:

$ echo "$info" |
sed -n 's/^{"version":[0-9][0-9]*,"config":{"(segment.bytes)":"([0-9][0-9]*)","retention.bytes":"[0-9][0-9]*"}}$/1:2/p'
segment.bytes:10737555

The above will work in any sed.

Answered by Ed Morton on December 24, 2021

You can try piping your $info variable though this sed call:

echo "$info" | sed -E '/"segment.bytes"/s/.*"(segment.bytes)":"([^"]+)".*/1:2/'

It will look for a line with the pattern "segment.bytes" and extract the segment.bytes string and the string in the following parentheses (defined as "anything but "" for simplicity) into the capture groups 1 and 2, and print "capture group 1", ":", and "capture group 2".

(Note that the option to activate extended regular expressions may vary depending on your sed version. -E is now POSIX standard and works on current GNU, MacOS and BSD sed, but if it fails, consult the man page on how to activate ERE)

To be more selective, try

sed -E '/"segment.bytes":"[0-9]+"/s/.*"(segment.bytes)":"([0-9]+)".*/1:2/'

which will only accept an integer value, both in the line search and in the value capturing part.

Answered by AdminBee on December 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP