Only one command line in PROJ.4 - proj

I would like to know if there are a way to write only one command line to obtain the expected results. I explain:
When you write this :
$ proj +proj=utm +zone=13 +ellps=WGS84 -f %12.6f
If you want to recieved the output data:
500000.000000 4427757.218739
You must to write in another line with the input data:
-105 40
Is it possible to write concatenated command line as this stile?:
$ proj +proj=utm +zone=13 +ellps=WGS84 -f %12.6f | -105 40
Thank you

I also ran into this problem and found the solution:
echo -105 40 | proj +proj=utm +zone=13 +ellps=WGS84 -f %12.6f
That should do the trick.
If you need to do this e.g. from within c#, the command you'd use is this:
cmd.exe /c echo -105 40 | proj +proj=utm +zone=13 +ellps=WGS84 -f %12.6f
Note: you may need to double up the % as the command processor interprets this as a variable.

Related

In Bash, How To Sort Echo Output from JQ?

I want to make automatic script to parse JSON for some value and echo-ing it to somewhere (in this case of test, terminal). Here is my complicated code:
for ((i = 0 ; i < 34 ; i++)); do
echo " \
$(curl -s https://data.covid19.go.id/public/api/prov.json | jq -r ".list_data[$i] .key"): \ # ex. Output: DKI Jakarta
$(curl -s https://data.covid19.go.id/public/api/prov.json | jq -r ".list_data[$i] .jumlah_kasus")"; # ex. Output: 580584
done
With this loop I got 34 lines:
DKI JAKARTA: 580584
JAWA BARAT: 402548
JAWA TENGAH: 265345
JAWA TIMUR: 178799
KALIMANTAN TIMUR: 79876
RIAU: 72361
SULAWESI SELATAN: 65330
DAERAH ISTIMEWA YOGYAKARTA: 65265
BANTEN: 59091
SUMATERA BARAT: 53125
BALI: 51499
SUMATERA UTARA: 36854
KALIMANTAN SELATAN: 36645
SUMATERA SELATAN: 29725
KEPULAUAN RIAU: 27854
KALIMANTAN TENGAH: 26719
LAMPUNG: 22731
KEPULAUAN BANGKA BELITUNG: 21976
PAPUA: 21150
NUSA TENGGARA TIMUR: 19977
ACEH: 19577
SULAWESI UTARA: 16633
KALIMANTAN BARAT: 15585
SULAWESI TENGAH: 13977
KALIMANTAN UTARA: 13466
JAMBI: 13332
NUSA TENGGARA BARAT: 13197
SULAWESI TENGGARA: 11948
PAPUA BARAT: 11682
BENGKULU: 10778
MALUKU: 9067
SULAWESI BARAT: 6043
GORONTALO: 5913
MALUKU UTARA: 5828
My question is: How can I sort the lines alphabetically with keeping province name and value synced?
E.g. like this:
ACEH: 19577
BALI: 51499
# etc...
Any answer will be appreciated, thank you. Let me know if there are something unclear so I can explain it.
Is this what you expected :
curl -s https://data.covid19.go.id/public/api/prov.json |\
jq -r '.list_data|sort_by(.key)[]|"\(.key): \(.jumlah_kasus)"'
Output stuff as one line with unique separator, sort, then replace that separtor with a newline.
for ...; do
echo "$(one)!$(two)"
done | sort | tr '!' '\n'

Arithmetic in web scraping in a shell

so, I have the example code here:
#!/bin/bash
clear
curl -s https://www.cnbcindonesia.com/market-data/currencies/IDR=/USD-IDR |
html2text |
sed -n '/USD\/IDR/,$p' |
sed -n '/Last updated/q;p' |
tail -n-1 |
head -c+6 && printf "\n"
exit 0
this should print out some number range 14000~15000
lets start from the very basic one, what I have to do in order to print result + 1 ? so if the printout is 14000 and increment it to 1 become 14001. I suppose the result of the html2text is not calculatable since it should be something like string output not integer.
the more advance thing i want to know is how to calculate the result of 2 curl results?
What I would do, bash + xidel:
$ num=$(xidel -se '//div[#class="mark_val"]/span[1]/text()' 'https://url')
$ num=$((${num//,/}+1)) # num was 14050
$ echo $num
Output
14051
 Explanations
$((...))
is an arithmetic substitution. After doing the arithmetic, the whole thing is replaced by the value of the expression. See http://mywiki.wooledge.org/ArithmeticExpression
Command Substitution: "$(cmd "foo bar")" causes the command 'cmd' to be executed with the argument 'foo bar' and "$(..)" will be replaced by the output. See http://mywiki.wooledge.org/BashFAQ/002 and http://mywiki.wooledge.org/CommandSubstitution
Bonus
You can compute directly in xidel, thanks Reino using xquery syntax :
$ xidel -s <url> e 'replace(//div[#class="mark_val"]/span[1],",","") + 1'
And to do addition arithmetic of 2 values :
$ xidel -s <url> -e '
let $num:=replace(//div[#class="mark_val"]/span[1],",","")
return $num + $num
'

converting bash output to JSON / Dictionary

I am trying to create a JSON compatible output in bash that can be read by nodejs & python:
{"link":XX,"signal":YY,"noise":ZZ}
here's the unfiltered result:
iwconfig wlan0
wlan0 IEEE 802.11bg ESSID:"wifi#someplace" Nickname:"<WIFI#REALTEK>"
Mode:Managed Frequency:2.452 GHz Access Point: C8:4C:75:20:B4:8E
Bit Rate:54 Mb/s Sensitivity:0/0
Retry:off RTS thr:off Fragment thr:off
Encryption key:A022-1191-3A Security mode:open
Power Management:off
Link Quality=100/100 Signal level=67/100 Noise level=0/100
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
But after applying my filters:
iwconfig wlan0 | grep Link | tr -d '/100' | tr '=' ' ' | xargs | awk '{printf "{\"link\":"$3",\"signal\":"$6",\"noise\":"$9"}"}'
I am getting erratic and incomplete results:
{"link":98,"signal":6,"noise":}
{"link":Signal,"signal":Noise,"noise":}
The "noise" value is never captured, and sometimes printf returns the wrong chunk.
Is there a more 'reliable' way of doing this ?
The problem with the code in your question is here:
tr -d '/100'
What that command does it simply delete all the characters: '/', '1', '0'.
From the manual for tr,
-d, --delete
delete characters in SET1, do not translate
Thats not something you'd want. What you want is to replace the entire string /100 with "".
Use: sed 's/\/100//g' instead.
... | grep Link | sed 's/\/100//g' | tr '=' ' ' | awk '{printf "{\"link\":"$3",\"signal\":"$6",\"noise\":"$9"}"}'
You could restructure the output using perl, by piping the output through the following command:
perl -n -E 'if ($_ =~ qr{Link Quality=(\d+)/100.*?Signal level=(\d+)/100.*?Noise level=(\d+)/100}) { print qq({"link":$1,"signal":$2,"noise":$3}); }'
Using awk it is quite simple:
awk -F '[ =/]+' '$2=="Link"{printf "{\"%s\":%s,\"%s\":%s,\"%s\":%s}\n",
$2, $5, $6, $8, $10, $12}'
{"Link":100,"Signal":67,"Noise":0}

Awk with function calling error in redirection

awk -F "|" 'function decToBin(dec) { printf "ibase=10; obase=2; $dec" | bc; } BEGIN {print $3" "$4" "$5" "$6" "$7" "decToBin($8)}' $Input
where Input is the path to file having
1|2|1.00|0.46|0.44|1.12|49.88|3
2|2|1.00|0.45|0.55|1.13|50.12|11
It was working correctly without function calling but after introducing function decToBin() it gives error. it gives error as
awk: fatal: expression for `|' redirection has null string value
got stuck dont know how to do that
please need help
myawkscript.awk:
function decToBin(dec) {
cmd="echo 'ibase=10; obase=2;" dec ";'|bc";
cmd|getline var
return var
}
//{print $3" "$4" "$5" "$6" "$7" "decToBin($8)}
Then
gawk -F"|" -f myawkscript.awk myfile
Gives you
1.00 0.46 0.44 1.12 49.88 11
1.00 0.45 0.55 1.13 50.12 1011
as expected
This can't work. bc is taken as the name of a variable, not the name of a command (awk doesn't behave like the shell). As the variable is undefined, it is treated as the null string. You must quote the command name:
$ awk 'BEGIN {printf "1+1\n" | "bc"}' /dev/null
2
In addition, $dec is not the value of dec, but the value of field number dec. Again, awk is not the shell. What you rather want it something like this:
$ awk 'BEGIN {dec = 21; printf "%d+%d\n", dec, dec | "bc"}' /dev/null
42

find and replace script (difficult issue...NEED HELP!)

I've written a function in zsh to find and replace a specific number with a keyword that I'll use later on in a larger script. Here's what I've got:
function replace_metal() {
for file in "$#"; do
[ -f "$file" ] && mv $file $file.old
# replace metal
awk '/^28\s/ { gsub(/28\s/, "METAL") }; { print }' $file.old > $file
# remove temporary files
rm -f $file.old
done
}
The awk portion works fine when I run it on the command line but while in the script, it fails to parse the file and replace the number with the keyword. I'm not sure why it fails. I've written a function that is similar that works without any trouble:
function fix_filename() {
for file in "$#"; do
[ -f "$file" ] && mv $file $file.old
# fix filename
awk '{ gsub(/myFileName/,FILENAME); print }' $file.old > $file.tmp
# clean up filename
awk '{ gsub(/.gjf.old/,""); print }' $file.tmp > $file
# remove temporary files
rm -f $file.old $file.tmp
done
}
I'm especially confused as to why awk won't work in the replace_metal function but will on the command line. If anyone can explain that, I'd really appreciate it.
Here's an example portion of a file that I'd run this script on. They are cartesian coordinates for a molecular geometry program I use.
6 4.387152 -0.132561 1.145384
6 4.435130 0.035315 -0.261758
6 3.241800 0.069735 -1.002575
7 2.023205 -0.053248 -0.382329
6 1.948032 -0.217668 0.977856
6 3.120408 -0.260395 1.759133
8 0.936529 -0.001059 -1.144164
28 -0.810634 -0.374713 -0.376819
7 -1.066408 1.593331 -0.221421
6 -2.101594 2.162030 0.386527
6 -3.220999 1.475281 0.925467
7 -2.581803 -0.796964 0.180331
6 -3.412540 0.082878 0.747753
6 -0.299269 -2.264241 -0.449077
1 5.304344 -0.163663 1.737743
1 5.382399 0.136858 -0.794636
1 3.185977 0.187888 -2.085134
1 0.932373 -0.311671 1.366224
1 3.017555 -0.393258 2.837678
1 -2.114644 3.263364 0.463786
1 -4.007715 2.050042 1.415626
1 -4.379471 -0.313239 1.099097
1 -0.572811 -2.828718 0.461055
1 0.789786 -2.379489 -0.603095
1 -0.795666 -2.747919 -1.311858
6 -3.146815 -2.155894 0.046938
1 -2.990568 -2.540510 -0.972499
1 -2.672661 -2.865421 0.746200
1 -4.233217 -2.149944 0.247135
6 -0.086130 2.536630 -0.792152
1 0.886270 2.480474 -0.265799
1 0.102603 2.306402 -1.853394
1 -0.445050 3.580750 -0.720938
Items in the first column are the only things that can be changed. Items in the other three columns should not ever change.
Thanks for your help!
the problem is the escaping of the "\"-character. Experiment with "\\s" or even "\\\\s". If you don't run the script directly, the "\"-character is evaluated two times: at first by the shell and then by awk. Anyway, you solution is way too complicated.
Try:
sed -i "s/^28 /METAL/" file
sed -i means substitute in place, so you don't have to copy the file "file" to "file.old" and then back again to "file".
Zsh has a built-in function to escape strings:
f="to be escaped"
print ${(q)f}
HTH Chris
If you can't win and quoting hell drives you mad (and you know there's a space and not a tab), just cheat:
awk '/^28 / { gsub(/^28 /, "METAL ") }; { print }' $file
... or else use [[:space:]] instead of \s, it appears GNU awk doesn't understand \s. For me, even plain
[0 1047 19:39:10] ~/temp/stack % gawk '/^28\s/ { gsub(/28\s/, "METAL") }; { print }' data
fails to replace. (Also, don't replace your space away if it's the only thing separating columns 1 and 2: replace with "METAL " or replace just /^28/.