TransWikia.com

Parse a string using keywords

Unix & Linux Asked by Beaker on October 31, 2021

I am using a bash command, gps location, that returns a date, time and location information.

[john@hostname :~/develp] $ gps location
Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}

I want to write the longitude to a file, before I get there I need to correctly parse the string.

[john@hostname :~/develp] $ variable=`gps location | awk '/"longitude":/ {print $9}'`
[john@hostname :~/develp] $ echo $variable
"133.453",
[john@hostname :~/develp] $

Currently, awk isn’t searching for longitude, it solely is taking the whole string and finding the 9th string. Ideally, I would like to use a regex/keyword approach and find longitude and then the next string after. I have tried using grep | cut also tried sed. No luck, best I can do is using awk.

7 Answers

Done with below awk command and it worked fine

cat filename

Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}

command

awk '{for(i=1;i<=NF;i++){if($i ~ /latitude/){print $(i+1)}}}' filename

output

"34.321"

Python

#!/usr/bin/python
a="""Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}"""

b=a.split(":")
for i in range(0,len(b),1):
    if "longitude" in b[i]:
        print b[i+1].split(",")[0]

output

 "133.453"

Answered by Praveen Kumar BS on October 31, 2021

You can extract the substring using bash builtins, specifically by using only parameter substitutions:

v=$(gps location)
v1=${v#*"longitude": "}
echo "${v1%%"*}"

Wherein we remove everything upto longitude": " in the variable v starting from left. Then in the next step we remove everything upto the last " starting from right. What remains are the longitudinal coordinates.

Answered by Rakesh Sharma on October 31, 2021

Some ideas:

grep -o longitude.:.* < in | grep -o '[0-9.]*' | head -1

grep -o longitude.:.* < in | cut -f3 -d'"'

People often forget the humble tr:

grep -o longitude.:.* < in | tr -dc 0-9., | cut -f1 -d,

or even better:

tr -dc ' La-z0-9.' < in | grep -o longitude.[0-9.]* | cut -f2 -d' '

That last one will make more sense if you realise that the first step produces

Location date 160720 time 190122 latitude 34.321 longitude 133.453 altitude 30m

which as you can see removes a lot of the distraction :-)

Answered by user339730 on October 31, 2021

If you want to try this without jq (e.g. because it is unavailable), and the output is always a one-liner as implied by your example, the following sed approach would also work:

sed -r 's/.*"longitude": "([^"]+)".*/1/'

This will

  • look for a string enclosed in double-quotes ( "([^"]+)", i.e. starting " followed by a string containing "anything but "" until the closing "), where the enclosed content is defined as "capture group" ( ... ), that occurs immediately after a string "longitude":
  • and replace basically the entire line with the content of the capture group (1) - in your case, the actual value of the longitude

Test:

~$ echo 'Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' | sed -r 's/.*"longitude": "([^"]+)".*/1/'
133.453

Answered by AdminBee on October 31, 2021

if you can't install jq, you can do it in pure bash using a loop over cut.

i=1
words=$(gps location)
word=$(echo $words | cut -d',' -f$i)
while ( [ -n "$word" ] )
  do
  echo $word | grep longitude | cut -d' ' -f2
  (( i+=1 ))
  word=$(echo $words | cut -d',' -f$i)
done

Answered by Michael Bölting on October 31, 2021

Unfortunately I don't have enough reputation to leave comments, but to expand upon Ed Morton's answer: if you call jq with the -r option, it will automatically strip quotes when the output is just a string (as it is in your case):

$ echo 'Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' | cut -d':' -f2- | jq -r .longitude
133.453

Answered by David Husz on October 31, 2021

Strip off the Location: and you're left with JSON:

$ echo '{"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' |
    jq .longitude
"133.453"

See in the man page if gps has an option to not print the Location: keyword up front, if not stripping it is easy, e.g.:

$ echo 'Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' |
    cut -d':' -f2- | jq .longitude
"133.453"

or:

$ echo 'Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' |
    sed 's/Location://' | jq .longitude
"133.453"

Answered by Ed Morton on October 31, 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