Regular Expression in Tcl to parse a line - tcl

i need a regular expression to separate left and right part of this pattern . . . . . :
for e.g.
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . : alumnus.co.in
Description . . . . . . . . . . . : Microsoft ISATAP Adapter
Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
and store them into two variable.
i have written this regular expression
regexp {([[a-z]*[0-9]*.*[0-9]*[a-z]*]*" "):([[a-z]*[0-9]*.*[0-9]*[a-z]*]*)} 6*rag5hu. . :4ku5-1a543m match a b
but it is not working.
Any help will be appreciated.

I would do this:
set text {Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . : alumnus.co.in
Description . . . . . . . . . . . : Microsoft ISATAP Adapter
Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes}
foreach line [split $text \n] {
if {[regexp {^(.+?)(?: \.)+ : (.+)$} $line -> name value]} {
puts "$name => $value"
}
}
outputs
Media State => Media disconnected
Connection-specific DNS Suffix => alumnus.co.in
Description => Microsoft ISATAP Adapter
Physical Address. => 00-00-00-00-00-00-00-E0
DHCP Enabled. => No
Autoconfiguration Enabled => Yes
This uses a non-greedy quantifier (+?), and that make every quantifier in the regex non-greedy. You then require the anchors so that the bits you want to capture contain all the text you need.

Borrowing the definition of text:
package require textutil
foreach line [split $text \n] {
lassign [::textutil::splitx [string trim $line] {\s*(?:\. )+:\s*}] a b
puts "a: $a\nb: $b"
}
Giving the output
a: Media State
b: Media disconnected
a: Connection-specific DNS Suffix
b: alumnus.co.in
a: Description
b: Microsoft ISATAP Adapter
a: Physical Address
b: 00-00-00-00-00-00-00-E0
a: DHCP Enabled
b: No
a: Autoconfiguration Enabled
b: Yes
Documentation:
foreach,
lassign,
package,
puts,
split,
string,
textutil (package)

Related

My Tcl expect script on Centos 5.5 or 8.2 tries to ssh to a Windows 10 machine and connects but can't reliably get output

I have a Tcl script that uses Expect on a CentOS 5.5 (old legacy work environment) or a CentOS 8.2 machine that opens an SSH session to a Windows 10 machine. I'm able to successfully connect but the data I get from $expect_out(buffer) is not correct. I seem to just get snippets of the output I expect as well as some unexpected characters that seem to move the output around the screen. When I watch in putty as the script runs, after the password is input the putty screen is cleared and "Microsoft Windows..." is in the first line of the window indicating the start of the ssh session. Then I can follow the commands I expect and the output on the screen looks good but it stops once it gets to the bottom of the putty window. Then my "puts" of the data after exiting the ssh session seem to just get overlayed on the data that was already in the putty window and my prompt and cursor will be in the middle of the output. Does Windows send back screen location type characters or anything that will screw up my data that I need to parse out? This behavior is identical on two different Windows 10 machines. Manually doing this from the command line works fine.
Centos 5.5, tcl 8.5, expect 5.43.0
Centos 8.2.2004, tcl 8.6, expect 5.45.4
My script just gets "netsh wlan show int", "ipconfig" and "dir". This is the output on the screen as all output is confined to the screen...
Microsoft Windows [Version 10.0.18363.1139] (c) 2019 Microsoft Corporation. All rights reserved.
dell-lat-7300#SR3-DELL-AX C:\Users\DELL-LAT-7300>
===========end ipconfig data 2=============
Hosted network status: Not available
==========start dir data 3===================
DELL-LAT-7300>ipconfig ipconfig
Connection-specific DNS Suffix . :
IPv6 Address. . . . . . . . . . . : ip
IPv6 Address. . . . . . . . . . . : ip
IPv6 Address. . . . . . . . . . . : ip
Temporary IPv6 Address. . . . . . : ip
Link-local IPv6 Address . . . . . : ip
IPv4 Address. . . . . . . . . . . : ip
Subnet Mask . . . . . . . . . . . : ip
Default Gateway . . . . . . . . . : ip
ip
Ethernet adapter Bluetooth Network Connection 2:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
dell-lat-7300#SR3-DELL-AX C:\Users\DELL-LAT-7300>
===========end dir data 3============= Media disconnected Connection-specific DNS Suffix . :
[user#pc-hawk ~]$ wlan0:
Connection-specific DNS Suffix . :
IPv6 Address. . . . . . . . . . . : ip
IPv6 Address. . . . . . . . . . . : ip
IPv6 Address. . . . . . . . . . . : ip
Temporary IPv6 Address. . . . . . : ip
Link-local IPv6 Address . . . . . : ip
IPv4 Address. . . . . . . . . . . : ip
Subnet Mask . . . . . . . . . . . : ip
Default Gateway . . . . . . . . . : ip
ip
Ethernet adapter Bluetooth Network Connection 2:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
dell-lat-7300#SR3-DELL-AX C:\Users\DELL-LAT-7300>dir
Volume in drive C is OS Volume Serial Number is 4C91-A066
Directory of C:\Users\DELL-LAT-7300
06/21/2020 09:23 PM <DIR> . 06/21/2020 09:23 PM <DIR>
09/16/2019 10:31 AM <DIR> .idlerc
==========start netsh data 1============== netsh wlan show int
My Tcl Expect script:
package require Expect
set client_ip "10.10.10.203"
set username "username"
set password "password"
set rawdata1 ""
set rawdata2 ""
set rawdata3 ""
set rawdata4 ""
set timeout 10
spawn ssh $client_ip -l $username
expect {
timeout {
expect *;
exit;
}
-nocase "(yes/no)?" {
after 500
exp_send "yes\r\n"
exp_continue
}
-nocase "password:" {
after 500
exp_send "$password\r\n"
exp_continue
}
-nocase ">" { }
}
catch {expect ">"}
catch {expect *}
set rawdata1 ""
after 2000
exp_send "netsh wlan show int\r\n"
expect {
timeout { }
-re ">" { }
}
set rawdata1 $expect_out(buffer)
catch {expect ">"}
catch {expect *}
after 2000
exp_send "ipconfig\r\n"
expect {
timeout { }
-re ">" { }
}
set rawdata2 $expect_out(buffer)
catch {expect ">"}
catch {expect ">"}
catch {expect *}
after 2000
exp_send "dir\r\n"
expect {
timeout { }
-re ">" { }
}
set rawdata3 $expect_out(buffer)
catch {expect ">"}
catch {expect ">"}
catch {expect ">"}
catch {expect *}
after 2000
exp_send "exit\r\n"
puts "\n\n==========start netsh data 1==============\n$rawdata1\n===========end netsh data 1=============\n\n"
puts "\n\n==========start ipconfig data 2==============\n$rawdata2\n===========end ipconfig data 2=============\n\n"
puts "\n\n==========start dir data 3==============\n$rawdata3\n===========end dir data 3=============\n\n"
exit
Based on feedback, from the output of od -c and expect -d I see a number of Escape chars (033 or 0x1b) followed by ] and then an assortment of characters. I suspect this is why my output is all over the screen. But the output of expect -d makes it look like I get a bunch of these escaped characters instead of my valid data. Even if I can clear out these characters it doesn't even look like my data is there. Any suggestions on how to get valid data out of the Win10?
I expect this from "netsh wlan show int"
There is 1 interface on the system:
Name : wlan0
Description : Intel(R) Wi-Fi 6 AX200 160MHz
GUID :
Physical address : mac
State : disconnected
Radio status : Hardware On
Software On
Hosted network status : Not available
snippet from expect -d where I send "netsh wlan show int\r"
expect: does "
\r\n\u001b[2J\u001b[?25l\u001b[m\u001b[H\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nr\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nr\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\u001b[H\u001b]0;c:\windows\system32\cmd.exe\u0007\u001b[?25h\u001b[?25lMicrosoft
Windows [Version 10.0.8363.1198]\u001b[18X\u001b[18C\r\n(c) 2019
Microsoft Corporation. All rights
reserved.\u001b[9X\u001b[9C\r\n\u001b[61X\u001b[61C\r\ndell-lat-7300#SR3-DELL-AX
C:\Users\DELL-LAT-7300>\u001b]0;Administrator:
c:\windows\system32\cmd.exe\u0007\u001b[?25h" (spawn_id exp6) match
glob pattern "(yes/no)?"? no "password:"? no "7300>"? yes expect: set
expect_out(0,string) "7300>" expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "
\r\n\u001b[2J\u001b[?25l\u001b[m\u001b[H\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\rn\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\rn\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\u001b[H\u001b]0;c:\windows\system32\cmd.exe\u0007\u001b[?25h\u001b[?25lMicrosoft
Windws [Version 10.0.18363.1198]\u001b[18X\u001b[18C\r\n(c) 2019
Microsoft Corporation. All rights
reserved.\u001b[9X\u001b[9C\r\n\u001b[61X\u001b[61C\r\ndell-lat-7300#SR3-DELL-X
C:\Users\DELL-LAT-7300>" send: sending "netsh wlan show int\r" to {
exp6 }
expect: does "\u001b]0;Administrator:
c:\windows\system32\cmd.exe\u0007\u001b[?25h" (spawn_id exp6) match
regular expression "7300>"? no
expect: does "\u001b]0;Administrator:
c:\windows\system32\cmd.exe\u0007\u001b[?25h\u001b[?25lnetsh wlan show
int\r\n\u001b[?25h" (spawn_id exp6) match regular expression "7300>"?
o
expect: does "\u001b]0;Administrator:
c:\windows\system32\cmd.exe\u0007\u001b[?25h\u001b[?25lnetsh wlan show
int\r\n\u001b[?25h\u001b[?25l\u001b[HMicrosoft Windows [Version
10.0.1363.1198]\u001b[137X\u001b[137C\r\n(c) 2019 Microsoft Corporation. All rights
reserved.\u001b[128X\u001b[128C\r\n\u001b[180X\u001b[180C\r\ndell-lat-7300#SR3-DELL-AX
C:\Users\DELL-LAT-7300>netsh wlan show
int\u001b[100X\u001b[100C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[10X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u00b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u01b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\nu001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\rn\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180Cr\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[18C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[80C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u01b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\r\n\u001b[180X\u001b[180C\u001b[5;1H\u001b]0;Administrator:
c:\windows\system32\cmd.exe - ntsh wlan show int\u0007\u001b[?25h"
(spawn_id exp6) match regular expression "7300>"? yes expect: set
expect_out(0,string) "7300>" expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\u001b]0;Administrator:
c:\windows\system32\cmd.exe\u0007\u001b[?25h\u001b[?25lnetsh wlan show
int\r\n\u001b[?25h\u001b[?25l\u001b[HMicrosoft Windos [Version
10.0.18363.1198]\u001b[137X\u001b[137C\r\n(c) 2019 Microsoft Corporation. All rights
reserved.\u001b[128X\u001b[128C\r\n\u001b[180X\u001b[180C\r\ndell-lat-7300#SR-DELL-AX
C:\Users\DELL-LAT-7300>"
od -c win10_ssh.log
0000000 \n \n = = = = = = = = = = s t a r
0000020 t n e t s h d a t a 1 = =
0000040 = = = = = = = = = = = = \n 033 [ ?
0000060 2 5 l n e t s h w l a n s h
0000100 o w i n t \r \n 033 [ ? 2 5 h 033 [
0000120 ? 2 5 l 033 [ H M i c r o s o f t
0000140 W i n d o w s [ V e r s i o
0000160 n 1 0 . 0 . 1 8 3 6 3 . 1 1 9
0000200 8 ] 033 [ 1 3 7 X 033 [ 1 3 7 C \r \n
...

Laravel Error : Function name must be a string

$files = $request->file('attachment');
$attachmentDataPush = NULL;
if ($request->hasfile('attachment')) {
foreach ($files as $file) {
$message->attach($file->getRealPath(), [
'as' => $file->getClientOriginalName(),
'mime' => $file->getMimeType()
]);
$filename = 'AttachmentsBox/' . $message->getId() . '/' . $file->getClientOriginalName();
Storage::put($filename, $file->get());
$attachmentDataPush = $attachmentDataPush . "<" . $file()->getClientOriginalName() . ">";
}
}
I want to add the code I wrote in $ attachmentDataPush side by side in <> but it gives an error. "Function name must be a string" What do you think may be the problem. ?
$attachmentDataPush = $attachmentDataPush . "<" . $file()->getClientOriginalName() . ">";
Line gives an error.I will insert the transaction into the database.
$attachmentDataPush = $attachmentDataPush . "<" . $file->getClientOriginalName() . ">";
I functioned as file (). I accidentally put brackets. The top one is correct.

jcifs fails to resolve a DFS url

When trying to access an SmbFile with a DFS URL, the jcifs library fails. But when I use the UNC returned by dfsutil it works.
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication( domain, user, pass );
SmbFile folder = new SmbFile(path,auth);
If path is set to
smb://mydomain.example.com/ourdfs/go/to/my/folder
the call fails with
Exception in thread "main" jcifs.smb.SmbException: The network name cannot be found.
But it is successful when invoked with the resolved name
dfsutil diag viewdfspath \\mydomain.example.com\ourdfs\go\to\my\folder
The DFS Path <\\mydomain.example.com\ourdfs\go\to\my\folder>
resolves to -> <\\someserver.example.com\sharename$\my\folder>
Then the following url works for path
smb://someserver.example.com/sharename$/my/folder
How do I set up jcifs to handle DFS properly i.e. not having to translate urls thru dfsutil?
The solution is to set the WINS configuration. IPCONFIG /ALL will show the information:
Connection-specific DNS Suffix . : MYDOMAIN.EXAMPLE.COM
Description . . . . . . . . . . . : Ethernet Connection
Physical Address. . . . . . . . . : DE-AD-BE-EF-F0-0D
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
IPv4 Address. . . . . . . . . . . : 10.10.1.42(Preferred)
Subnet Mask . . . . . . . . . . . : 255.0.0.0
Lease Obtained. . . . . . . . . . : December 3, 2018 09:03:04 AM
Lease Expires . . . . . . . . . . : December 9, 2018 09:03:04 AM
Default Gateway . . . . . . . . . : 10.10.1.1
DHCPv4 Class ID . . . . . . . . . : O-mobile
DHCP Server . . . . . . . . . . . : 10.10.11.13
DNS Servers . . . . . . . . . . . : 10.10.4.48
10.10.4.56
Primary WINS Server . . . . . . . : 10.10.1.59
Secondary WINS Server . . . . . . : 10.10.2.58
NetBIOS over Tcpip. . . . . . . . : Enabled
The then configuration item has to be set as follows:
jcifs.netbios.wins=10.10.1.59
or by setting it with jcifs.Config.setProperty()

Exim script before queue

I need to open exim relay to a list of ips in a mysql database.
I think if I can run a script before a email is queued, I can do that. Is there a way?
Mail Enable for windows has a similar solution called "SMTP Inbound Command Scripting".
# configure
. . . . .
hide mysql_servers = localhost/myoneandonlybase/login/pass
hostlist myfriends = ${lookup mysql{SELECT ipaddr FROM submitters}}
. . . . .
acl_smtp_connect = acl_conn
acl_smtp_rcpt = acl_rcpt
acl_smtp_data = acl_data
. . . . .
begin acl
acl_conn:
accept hosts = +myfriends
. . . . .
acl_rcpt:
accept hosts = +myfriends
. . . . .
acl_data:
accept hosts = +myfriends
. . . . .
The default exim configuration file already has a hostlist relay_from_hosts that you can easily populate with an SQL lookup and get the desired result:
hide mysql_servers = localhost/myoneandonlybase/login/pass
hostlist relay_to_domains = ${lookup mysql{SELECT ipaddr FROM submitters}}
Nothing more than that is needed.

RegEx match for multiline in Perl

I have following data line i need to parse in Perl:
my $string='Upper Left ( 440720.000, 3751320.000) (117d38\'28.21"W, 33d54\'8.47"N)';
Here is my perl script:
if ($string=~ m/Upper Left\s+[(]\s+\d{1,6}[.]\d{1,3}[\,]\s+\d{1,6}[.]\d{1,3}[)]\s+[(](\d{1,3})d(\d{1,2})['](\d{1,2})[.](\d{1,2})/ig) {
$upperLeft="lat=". $1. 'd'. $2. "'". $3. ".". $4. '"W long='. $5. 'd'. $6. "'". $7. ".". $8. '"W';
print $upperLeft. "\n";
}
However this expression fails to 117d38'28.21" as lat and 33d54'8.47 as long. Note the space and '(' in the input $string which i use to create this regular expression.
What I am I doing wrong in extracting (117d38'28.21"W, 33d54'8.47"N) into 8 fields? Any help is appreciated.
You had several issues. The main being your regex just parsing up to lat, not lon.
What changed:
m/Upper Left\s+[(]\s+\d{1,6}[.]\d{1,3}[\,]\s+\d{1,6}[.]\d{1,3}[)]\s+[(](\d{1,3})d(\d{1,2})['](\d{1,2})[.](\d{1,2})/ig
m/Upper Left\s+[(]\s+\d{1,6}[.]\d{1,3}[\,]\s+\d{1,7}[.]\d{1,3}[)]\s+[(](\d{1,3})d(\d{1,2})['](\d{1,2})[.](\d{1,2})"([WE])[\,]\s(\d{1,3})d(\d{1,2})['](\d{1,2})[.](\d{1,2})"([NS])/ig
^-- Your test number was 7-digit big ^-- (1) ^-- (2) ^-- (3)
At the ending: (1) added group to deal with W/E (([WE])). (2) Added groups to extract lon number. (3) Added group to deal with N/S (([NS])).
Your code, corrected:
if ($string=~ m/Upper Left\s+[(]\s+\d{1,6}[.]\d{1,3}[\,]\s+\d{1,7}[.]\d{1,3}[)]\s+[(](\d{1,3})d(\d{1,2})['](\d{1,2})[.](\d{1,2})"([WE])[\,]\s(\d{1,3})d(\d{1,2})['](\d{1,2})[.](\d{1,2})"([NS])/ig) {
$upperLeft = "lat=" . $1 . 'd' . $2 . "'" . $3 . "." . $4 . '"' . $5 . " long=" . $6 . 'd' . $7 . "'" . $8 . "." . $9 . '"' . $10;
print $upperLeft. "\n";
}
Output:
lat=117d38'28.21"W long=33d54'8.47"N