Processing bash variable with sed
Solution 1
This can be solved via pure shell syntax. It does require a temp variable because of the parentheses (brackets) though:
#!/bin/bash
LATLNG="(53.3096,-6.28396)"
tmp=${LATLNG//[()]/}
LAT=${tmp%,*}
LNG=${tmp#*,}
Alternatively, you can do it in one go by playing with IFS
and using the read
builtin:
#!/bin/bash
LATLNG="(53.3096,-6.28396)"
IFS='( ,)' read _ LAT LNG _ <<<"$LATLNG"
Solution 2
SiegeX's answer is better for this particular case, but you should also know how to pass arbitrary text to sed
.
sed
is expecting filenames as its second, third, etc. parameters, and if it doesn't find any filenames, it reads from its standard input. So if you have text that you want to process that's not in a file, you have to pipe it to sed
. The most straightforward way is this:
echo "blah blah" | sed 's/blah/blam/g'
So your example would become:
LAT=$(echo "$LATLNG" | sed 's/(\(.*\),\(.*\))/\1/g')
LON=$(echo "$LATLNG" | sed 's/(\(.*\),\(.*\))/\2/g')
Alternate (better but more obscure) Methods
If you think there's any chance that $LATLNG
could begin with a dash, or if you want to be pedantic, you should use printf
instead of echo
:
printf '%s' "$LATLNG" | sed 's/foo/bar/g'
Or a "here document", but that can be a little awkward with the construct you're using:
LAT=$(sed 's/foo/bar/g' <<END
$LATLNG
END
)
Or if you're using bash
and not worried about portability, you can use a "here string":
sed 's/foo/bar/g' <<< "$LATLNG"
Solution 3
Here's a solution that will work in any POSIX shell:
parse_coordinates () {
IFS='(), ' # Use these characters as word separators
set -f # Disable globbing
set $1 # Split $1 into separate words
set +f # Restore shell state
unset IFS
LAT=$2 # $1 is the empty word before the open parenthesis
LON=$3
}
parse_coordinates "$LATLNG"
Here's another equally portable solution that parses the specific syntax used.
LAT=${LATLNG%\)} # strip final parenthesis
LAT=${LAT#\(} # strip initial parenthesis
LON=${LAT##*[, ]} # set LON to everything after the last comma or space
LAT=${LAT%%[, ]*} # set LAT to everything before the first comma or space
Related videos on Youtube
conorgriffin
Updated on September 17, 2022Comments
-
conorgriffin almost 2 years
bash variable LATLNG contains a latitude & longitude value in brackets like so
(53.3096,-6.28396)
I want to parse these into a variable called LAT and LON which I'm trying to do via sed like so
LAT=$(sed "s/(\(.*\),\(.*\))/\1/g" "$LATLNG")
LON=$(sed "s/(\(.*\),\(.*\))/\2/g" "$LATLNG")
However, I get the following error:
sed: can't read (53.3096,-6.28396): No such file or directory
-
Michael Dillon over 13 yearsLearn a scripting language like Python, Ruby, maybe even PERL, so that you don't have to force the shell to do everything for you. You can even get Javascript (Rhino) to run on a UNIX system and almost everyone needs to know some Javascript.
-
Kusalananda over 5 yearsFrom where does these values come? It would be more efficient to parse the latitude and longitude values out from the original source than adding an extra step by putting them in a
bash
variable.
-
-
i_saw_drones over 13 yearsFirst example will work only in bash, not in POSIX shell.
-
SiegeX over 13 years@gelraen hence the
#!/bin/bash
-
mikeserv about 10 yearsYou should probably do
set -- ...
There is a very good chance the first character is a-
. -
Ricardo Stuven about 8 yearsSee more expansions here: gnu.org/software/bash/manual/…