Reverse geocoding in BASH - error using variable as coordinates - bash

im trying to use variables instead of static coordinates in the code below, but without any succes.
What am i doing wrong here ?
stored_address=$(curl -s "http://maps.googleapis.com/maps/api/geocode/json?latlng="'${coor1}'","'${coor2}'"&sensor=false" | grep -B 1 "route" | awk -F'"' '/short_name/ {print $4}')
My curl works if I use coordinates instead of the two variables "'${coor1}'" and "'${coor2}'", could someone please point out the error, thanks :)
working example with static coordinates:
stored_address=$(curl -s "http://maps.googleapis.com/maps/api/geocode/json?latlng=56.433125,10.07003&sensor=false" | grep -B 1 "route" | awk -F'"' '/short_name/ {print $4}')

you're using hard quoting, i.e. you wrap your variables in '. lose the single quotes and the variables will be expanded correctly:
stored_address=$(curl -s "http://maps.googleapis.com/maps/api/geocode/json?latlng=${coor1},${coor2}&sensor=false" | grep -B 1 "route" | awk -F'"' '/short_name/ {print $4}')
from the bash man page:
Enclosing characters in single quotes (‘'’) preserves the literal value of each character within the quotes.

Related

One-liner POSIX command to lowercase string in bash

Problem
I have this comand:
sed $((SS - default_scripts))!d customScripts.txt
and it gives me Foo Bar.
I want to convert this to lowercase.
Attempt
When I tried using the | awk '{print tolower($0)}' command on it it returned nothing:
$($(sed $((SS - default_scripts))!d customScripts.txt) | awk '{print tolower($0)}')
Final
Please enlighten me on my typo, or recommend me another POSIX way of converting a whole string to lowercase in a compact manner. Thank you!
The pipe to awk should be inside the same command substitution as sed, so that it processes the output of sed.
$(sed $((SS - default_scripts))!d customScripts.txt | awk '{print tolower($0)}')
You don't need another command substitution around both of them.
Your typo was wrapping everything in $(...) and so first trying to execute the output of just the sed part and then trying to execute the output of the sed ... | awk ... pipeline.
You don't need sed commands nor shell arithmetic operations when you're using awk. If I understand what you're trying to do with this:
$(sed $((SS - default_scripts))!d customScripts.txt) | awk '{print tolower($0)}'
correctly then it'd be just this awk command:
awk -v s="$SS" -v d="$default_scripts" 'BEGIN{n=s-d} NR==n{print tolower($0); exit}' customScripts.txt

Bash, how to create an array in one line of code

how can I create an array in one step instead of two stages, like shown below?'
The example below was executed on a live Linux system.
POSITION=`volt |grep ate |awk '{print $4}'` #returns three integers
declare -a POSITION_ARRAY=($POSITION) #create an array
You don't need the intermediate variable, as wjandrea said. These two snippets are equivalent:
POSITION=$(volt | grep ate | awk '{print $4}')
declare -a POSITION_ARRAY=($POSITION)
# declare -a also works, but isn't needed in modern Bash
POSITION_ARRAY=( $(volt | grep ate | awk '{print $4}') )
If you know the output of the pipeline is witespace-delimited integers this will do what you want. But it isn't a safe way to populate an array from arbitrary command output, because unquoted expansions will be word-split and globbed.
The proper way to read a command's output into an array, split by lines, is with the readarray builtin, like so:
readarray -t POSITION_ARRAY < <(volt | grep ate | awk '{print $4}')
Simply put the command in the parentheses.
By the way, declare -a is not needed, and backticks are deprecated in favour of $().
POSITION_ARRAY=( $(volt | grep ate | awk '{print $4}') )
And FWIW you can merge the grep and AWK commands:
POSITION_ARRAY=( $(volt | awk '/ate/ {print $4}') )

shell script to extract text from a variable separated by forward slashes

I am trying to find a way to to extract text from a variable with words separated by a forward slash. I attempted it using cut, so here's an example:
set variable = '/one/two/three/four'
Say I just want to extract three from this, I used:
cut -d/ -f3 <<<"${variable}"
But this seems to not work. Any ideas of what I'm doing wrong? Or is there a way of using AWK to do this?
You need to remove the spaces before and after to = during string or variable assignment. And tell the cut command to print the 4th field.
$ variable='/one/two/three/four'
$ cut -d/ -f4 <<<"${variable}"
three
With the delimiter /, cut command splits the input like.
/one/two/three/four
| | | | |
1 2 3 4 5
that is, when it splits on first slash , you get an empty string as first column.
I think that the main problem here is in your assignment. Try this:
var='/one/two/three/four'
cut -d/ -f4 <<<"$var"
Here is an awk version:
awk -F\/ '{print $4}' <<< "$variable"
three
or
echo "$variable" | awk -F\/ '{print $4}'
three
PS to set a variable not need for set and remove spaces around =
variable='/one/two/three/four'

Alias if script matches variable, quotation issues

I'm trying to write an alias for a common command to cancel a process, but I'm having issues with the single and double quotations. This is my first attempt at Bash scripting and I'm a bit stumped.
lsof -i tcp:80 | awk '$1 == "Google" {print $2}'
This works as a stand-alone command and outputs the correct PID.
When I try formatting it as an alias though I'm having issues. I know the command is stopping at the first single quote by the way this is structure but I'm not sure how to fix it.
alias test='lsof -i tcp:80 | awk '$1=="Google" {print $2}''
There's no escape sequence for single quotes inside single quotes. You can't write \' like you might expect. So there are two options.
You can break out of single quotes, add an escaped single quote \', and then go back in, like so:
alias test='lsof -i tcp:80 | awk '\''$1 == "Google" {print $2}'\'
You can use double quotes. You then have to escape not just the double quotes inside the string but also the dollar signs.
alias test="lsof -i tcp:80 | awk '\$1 == \"Google\" {print \$2}'"
Try defining your alias like this
alias test='lsof -i tcp:80 | awk '"'"'$1=="Google" {print $2}'"'"
The single quotes ' must be escaped between double quotes ". To do so, the command has to be split into several parts to escape them differently. lsof -i tcp:80 | awk '$1=="Google" {print $2}' can be split on single quotes like this
lsof -i tcp:80 | awk
'
$1=="Google" {print $2}
'
Then quote with appropriate quotes
'lsof -i tcp:80 | awk'
"'"
'$1=="Google" {print $2}'
"'"
And merge every part together and you have your alias:
'lsof -i tcp:80 | awk'"'"'$1=="Google" {print $2}'"'"
Note that the first part does not contain any interpreted variable so it can be quoted with double quotes and merged with the second part. Thus the alias becomes
alias test="lsof -i tcp:80 | awk'"'$1=="Google" {print $2}'"'"
In almost every case where find yourself trying to define an alias, define a function instead.
testing () {
lsof -i tcp:80 | awk '$1=="Google" {print $2}'
}

How to pass a bash variable as value of awk parameter?

I would like to replace a variable inside the the awk command with a bash variable.
For example:
var="one two three"
echo $var | awk "{print $2}"
I want to replace the $2 with the var variable. I have tried awk -v as well as something like awk "{ print ${$wordnum} } to no avail.
Sightly different approach:
$ echo $var
one two three
$ field=3
$ echo $var | awk -v f="$field" '{print $f}'
three
$ field=2
$ echo $var | awk -v f="$field" '{print $f}'
two
You've almost got it...
$ myfield='$3'
$ echo $var | awk "{print $myfield}"
three
The hard quotes on the first line prevent interpretation of $3 by the shell. The soft quotes on the second line allow variable replacement.
You can concatenate parts of awk statements with variables. Maybe this is what you want in your script file:
echo $1|awk '{print($'$2');}'
Here the parts {print($ and the value of local variable $2 and );} are concatenated and given to awk.
EDIT: After some advice rather don't use this. Maybe as a one-time solution. It's better to get accustomed to doing it right right away - see link in first comment.

Resources