Jump to content

Am I able to sort out the columns in a Command Prompt?


Recommended Posts

Hello,
 

I have recently tried experimenting with a new feature that I want to add to my program. I wanted to test packet loss, so I opted into a command prompt that displays the necessary data that I want. Now I want to sort out the data by using column sorting if possible by using arrays. My question is: Are you able to sort them out on CMD or is it only Excel spreadsheets?

Below find the column I want to sort out:
 

Pinging google.ie [2a00:1450:400b:c01::5e] with 32 bytes of data:
Reply from 2a00:1450:400b:c01::5e: time=1033ms
Reply from 2a00:1450:400b:c01::5e: time=309ms
Reply from 2a00:1450:400b:c01::5e: time=37ms
Reply from 2a00:1450:400b:c01::5e: time=732ms

Ping statistics for 2a00:1450:400b:c01::5e:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 37ms, Maximum = 1033ms, Average = 527ms

I want to extract the Packet loss; the average along with all the results in the "time" column.

Looking forward for your response!

 

Kind Regards,

Supra

Edited by supraaxdd
Small mistake
Link to comment
Share on other sites

Here is one example of an attempted answer.  The answer being the desired presentation of string and/or array manipulation.

#include <ArrayMultiSortCase.au3> ; From https://www.autoitscript.com/forum/topic/198148-_arraymultisort-sort-multiple-columns-with-case-sensitivity/

$textD = _Cmd("Ping -t -n 4 google.ie", @ScriptDir) ; google-public-dns-b.google.com
;$textD = _Cmd("Ping", @ScriptDir) ; Ping usage - help
ConsoleWrite($textD & @CRLF)

$aArray = StringRegExp($textD, "(?m)(?:^.+time\h*=\h*(\d+)ms.*$)+", 3) ;|\h*Minimum\h*=\h*(\d+)ms.+?Maximum\h*=\h*(\d+)ms.+?Average\h*=\h*(\d+)ms.*$",3)

; _ArraySortC(ByRef $aArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0, $iPivot = 0, $iCase = 0, $iNumericalSort = 0)
_ArraySortc($aArray, 0, 0, 0, 0, 0, 0, 1) ; _ArraySortC() used to sort numerically.  _ArraySort() sorts alphabetically making "11", one one, smaller than "2", two.
_ArrayDisplay($aArray, "Pinging Times")
MsgBox(0, "", StringRegExpReplace($textD, "(?s).+(Packets:.+?\)).+(Average = \d+ms)", "$1" & @CRLF & "$2"))


Func _Cmd($sCmd, $sDir = "")
    Local $text = '', $Pid = Run(@ComSpec & " /c " & $sCmd, $sDir, @SW_HIDE, 2 + 4)
    While 1
        $text &= StdoutRead($Pid, False, False)
        If @error Then ExitLoop
        Sleep(10)
    WEnd
    While 1
        $text &= StderrRead($Pid)
        If @error Then ExitLoop
        ConsoleWrite(@LF & "!#------------------------# Error #---------------------------# " & @LF)
    WEnd
    Return $text
EndFunc   ;==>_Cmd

 

Link to comment
Share on other sites

4 hours ago, Malkey said:

Here is one example of an attempted answer.  The answer being the desired presentation of string and/or array manipulation.

#include <ArrayMultiSortCase.au3> ; From https://www.autoitscript.com/forum/topic/198148-_arraymultisort-sort-multiple-columns-with-case-sensitivity/

$textD = _Cmd("Ping -t -n 4 google.ie", @ScriptDir) ; google-public-dns-b.google.com
;$textD = _Cmd("Ping", @ScriptDir) ; Ping usage - help
ConsoleWrite($textD & @CRLF)

$aArray = StringRegExp($textD, "(?m)(?:^.+time\h*=\h*(\d+)ms.*$)+", 3) ;|\h*Minimum\h*=\h*(\d+)ms.+?Maximum\h*=\h*(\d+)ms.+?Average\h*=\h*(\d+)ms.*$",3)

; _ArraySortC(ByRef $aArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0, $iPivot = 0, $iCase = 0, $iNumericalSort = 0)
_ArraySortc($aArray, 0, 0, 0, 0, 0, 0, 1) ; _ArraySortC() used to sort numerically.  _ArraySort() sorts alphabetically making "11", one one, smaller than "2", two.
_ArrayDisplay($aArray, "Pinging Times")
MsgBox(0, "", StringRegExpReplace($textD, "(?s).+(Packets:.+?\)).+(Average = \d+ms)", "$1" & @CRLF & "$2"))


Func _Cmd($sCmd, $sDir = "")
    Local $text = '', $Pid = Run(@ComSpec & " /c " & $sCmd, $sDir, @SW_HIDE, 2 + 4)
    While 1
        $text &= StdoutRead($Pid, False, False)
        If @error Then ExitLoop
        Sleep(10)
    WEnd
    While 1
        $text &= StderrRead($Pid)
        If @error Then ExitLoop
        ConsoleWrite(@LF & "!#------------------------# Error #---------------------------# " & @LF)
    WEnd
    Return $text
EndFunc   ;==>_Cmd

 

Thanks for the response on this topic.

I have tested out your code and it worked just fine and thank you for that. Before I implement it into my actual code, may I ask how do you ping google? Do you ping it using the "Ping" command or do you specify to ping via CMD?

If you are doing it via CMD, could you please tell me which line of code says so?

 

Kind Regards,

Supra
 

Edit: Are you running CMD prior to the ping command by using the "Run" command in the second line of the _Cmd function? If not, where?

Edited by supraaxdd
Link to comment
Share on other sites

  • Moderators

@supraaxdd the _Cmd in this line:

$textD = _Cmd("Ping -t -n 4 google.ie", @ScriptDir) ; google-public-dns-b.google.com

Is a call to the _Cmd function below:

Func _Cmd($sCmd, $sDir = "")
    Local $text = '', $Pid = Run(@ComSpec & " /c " & $sCmd, $sDir, @SW_HIDE, 2 + 4)
    While 1
        $text &= StdoutRead($Pid, False, False)
        If @error Then ExitLoop
        Sleep(10)
    WEnd
    While 1
        $text &= StderrRead($Pid)
        If @error Then ExitLoop
        ConsoleWrite(@LF & "!#------------------------# Error #---------------------------# " & @LF)
    WEnd
    Return $text
EndFunc   ;==>_Cmd

A function in AutoIt processes all code between the Func and EndFunc keywords (look in the help file for more). One of the lines in the function is this:

Local $text = '', $Pid = Run(@ComSpec & " /c " & $sCmd, $sDir, @SW_HIDE, 2 + 4)

If you look in the help file, you will see the @ComSpec keyword (help file) is a reference to launching the command line window. In this case the code suggested is doing it with the @SW_HIDE (help file) parameter which makes it hidden. If you were to change that to @SW_SHOW, you will see the window pop up.

Clear things up? Any further questions please ask :)

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

6 hours ago, JLogan3o13 said:

@supraaxdd the _Cmd in this line:

$textD = _Cmd("Ping -t -n 4 google.ie", @ScriptDir) ; google-public-dns-b.google.com

Is a call to the _Cmd function below:

Func _Cmd($sCmd, $sDir = "")
    Local $text = '', $Pid = Run(@ComSpec & " /c " & $sCmd, $sDir, @SW_HIDE, 2 + 4)
    While 1
        $text &= StdoutRead($Pid, False, False)
        If @error Then ExitLoop
        Sleep(10)
    WEnd
    While 1
        $text &= StderrRead($Pid)
        If @error Then ExitLoop
        ConsoleWrite(@LF & "!#------------------------# Error #---------------------------# " & @LF)
    WEnd
    Return $text
EndFunc   ;==>_Cmd

A function in AutoIt processes all code between the Func and EndFunc keywords (look in the help file for more). One of the lines in the function is this:

Local $text = '', $Pid = Run(@ComSpec & " /c " & $sCmd, $sDir, @SW_HIDE, 2 + 4)

If you look in the help file, you will see the @ComSpec keyword (help file) is a reference to launching the command line window. In this case the code suggested is doing it with the @SW_HIDE (help file) parameter which makes it hidden. If you were to change that to @SW_SHOW, you will see the window pop up.

Clear things up? Any further questions please ask :)

Thank you for the fast response.

It certainly did clear alot of my questions up because I looked at the help file and I couldn't really make it out. Thank you so much! I also didn't realise that the @SW_HIDE was the hiding the window as I didn't pay that much attention to it. Thank you yet again. Great help from the community for about the 18th time :D

Edit: I know how the function works, I was just looking for the part that was starting the cmd in the backround :)

 

Edited by supraaxdd
Link to comment
Share on other sites

@JLogan3o13

Its now 9:30am here in Toowoomba. Last time I looked at this thread last night, there hadn't been a reply to my post.
Thanks for your reply. It is probably a better explanation than I would have provided.

Link to comment
Share on other sites

The OP uses sort/extract rather interchangably, so i took a different approach in efforts of the latter.  I needed to keep my CLI skills sharp :)

$pid = run('cmd /c powershell "' & "$ping=ping google.ie ; $ping -split '(time=\d+ms)' -split '(Lost = \d \(\d% loss\))' -split '(Average = \d+ms)' | select-string -Pattern time=,Lost,Average" , "" , @SW_HIDE , 0x2)

$out = ""

Do
    $out &= StdoutRead($pid)
Until @error

consolewrite($out)

 

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Why not use the Ping function to do it yourself in the script? No need to waste resources slicing up the output into an array and sorting it out before processing:

Global Const $HOST = "example.com"
Global Const $COUNT = 4
Example()

Func Example()
    Local $iLost = 0
    Local $iCounter = 0
    Do
        Ping($HOST)
        If @error Then $iLost += 1
        $iCounter += 1
    Until $iCounter = $COUNT
    Local $sMsg = StringFormat("Sent %i packets and recieved %i packets (%i lost)", $iCounter, $iCounter - $iLost, $iLost)
    ConsoleLog($sMsg & @CRLF)
EndFunc

Should work just as well :)

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

9 hours ago, Malkey said:

@JLogan3o13

Its now 9:30am here in Toowoomba. Last time I looked at this thread last night, there hadn't been a reply to my post.
Thanks for your reply. It is probably a better explanation than I would have provided.

@Malkey, Every explanation is worthy of listening. It doesn't hurt if you explained it another way :)

 

6 hours ago, iamtheky said:

The OP uses sort/extract rather interchangably, so i took a different approach in efforts of the latter.  I needed to keep my CLI skills sharp :)

$pid = run('cmd /c powershell "' & "$ping=ping google.ie ; $ping -split '(time=\d+ms)' -split '(Lost = \d \(\d% loss\))' -split '(Average = \d+ms)' | select-string -Pattern time=,Lost,Average" , "" , @SW_HIDE , 0x2)

$out = ""

Do
    $out &= StdoutRead($pid)
Until @error

consolewrite($out)

 

@iamtheky, thank you for your contribution to this thread. I will see how the first method works and if it doesn't suit me, I will take a look at this. Thank you anyways. :)

5 hours ago, TheDcoder said:

Why not use the Ping function to do it yourself in the script? No need to waste resources slicing up the output into an array and sorting it out before processing:

Global Const $HOST = "example.com"
Global Const $COUNT = 4
Example()

Func Example()
    Local $iLost = 0
    Local $iCounter = 0
    Do
        Ping($HOST)
        If @error Then $iLost += 1
        $iCounter += 1
    Until $iCounter = $COUNT
    Local $sMsg = StringFormat("Sent %i packets and recieved %i packets (%i lost)", $iCounter, $iCounter - $iLost, $iLost)
    ConsoleLog($sMsg & @CRLF)
EndFunc

Should work just as well :)

@TheDcoder, I opted in for the CMD option just because it's much simpler for me to get my head around it. I'm fairly new so I wouldn't know how half of the functions do in a code you would just give me. I prefer to "slice up the output", because I want to learn what happens and hopefully go without bothering you guys. Arrays for me are a complicated thing, I will need to study a bit more of AutoIT arrays in order to understand anything that is happening within the code and the program itself. Thank you for your response though, I will check it all out.

Thank you to everybody that contributed to this thread yet again. This is a fantastic community!

 

Kind Regards,

Supra

Link to comment
Share on other sites

6 hours ago, supraaxdd said:

I opted in for the CMD option just because it's much simpler for me to get my head around it.

It is easier than it seems, if you break my script into bits, it is very easy to understand.

The core of the code is the Ping function, which works on a simple concept, you give it a website and it will return you the time it took for the ping to go back and forth... if it fails, it sets the @error macro to something which is not zero (values are documented in helpfile).

Based on that information you can build your logic! You can have a loop and a variable to count the number of pings which have failed (lost), at the end of the loop you compare the total amount of times you pinged and the number of pings you lost to get the quality of the connection :D

Much simpler and easier... and doesn't require arrays at all! If I am understanding correctly, you want to measure the packet loss:

On 5/3/2019 at 11:40 PM, supraaxdd said:

I wanted to test packet loss

Which is not really directly related to sorting an array filled with string values... you have made the task complex for your own sake in my opinion. This is commonly referred to as the XY problem ;)

I recommend you try use the Ping function first, as it is the most efficient and objectively the correct way to do it in AutoIt :)

Feel free to ask questions, we are happy to answer them and don't see them as a burden which bothers us.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

1 hour ago, TheDcoder said:

Much simpler and easier... and doesn't require arrays at all!

That being said, would I be correct in any way that if I use the Ping function already supplied in AutoIT, it already measures packet loss, but I just need to find the correct way and structure of code to read it?

 

1 hour ago, TheDcoder said:

I recommend you try use the Ping function first, as it is the most efficient and objectively the correct way to do it in AutoIt

I already done so and it is working efficiently. If you want to see what I have done, please contact me, I can show you the code or .exe that I have so far. This question is also the reason I asked the question above.

 

1 hour ago, TheDcoder said:

Feel free to ask questions, we are happy to answer them and don't see them as a burden which bothers us.

Good to know that the community looks out for each other :)

 

Looking forward to your response.

 

Kind Regards,

Supra

Link to comment
Share on other sites

10 hours ago, supraaxdd said:

That being said, would I be correct in any way that if I use the Ping function already supplied in AutoIT, it already measures packet loss, but I just need to find the correct way and structure of code to read it?

Yes, absolutely. That is what I have demonstrated in my example :)

10 hours ago, supraaxdd said:

I already done so and it is working efficiently. If you want to see what I have done, please contact me, I can show you the code or .exe that I have so far. This question is also the reason I asked the question above. 

Not sure I understand the reason as you have explained... Maybe you are confusing the ping command with AutoIt's inbuilt Ping function?

If you are already using AutoIt's Ping function then that is great, but I am afraid in that case I am not sure why you want to take output from the ping command and sort it.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

6 hours ago, TheDcoder said:

Maybe you are confusing the ping command with AutoIt's inbuilt Ping function?

In the code, I used AutoIT's inbuilt function. My question was if that that inbuilt function had packet loss already. When I said "already supplied with AutoIT", I meant the inbuilt function, I just didn't know how to frase the question. My bad, sorry. :)

 

6 hours ago, TheDcoder said:

Yes, absolutely. That is what I have demonstrated in my example :) 

I will take a closer look at that function. Thanks for supplying me with the code.

 

Kind Regards,

Supra

Link to comment
Share on other sites

7 hours ago, supraaxdd said:

My question was if that that inbuilt function had packet loss already. When I said "already supplied with AutoIT", I meant the inbuilt function, I just didn't know how to frase the question. My bad, sorry. :)

No worries, it would have helped if you had asked this directly though :D

Allow me to explain, "packet loss" is simply the number of ping requests (packets) which fail.

So if you send 10 pings (10 packets), and 3 of them fail (no response or network error etc.), then you say that the packet loss is 3/10 (or 30%)

Packet loss is not a seperate fancy feature that needs to be implemented... if you can ping, you can also measure the packet loss ;)

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

14 hours ago, TheDcoder said:

No worries, it would have helped if you had asked this directly though :D

Allow me to explain, "packet loss" is simply the number of ping requests (packets) which fail.

So if you send 10 pings (10 packets), and 3 of them fail (no response or network error etc.), then you say that the packet loss is 3/10 (or 30%)

Packet loss is not a seperate fancy feature that needs to be implemented... if you can ping, you can also measure the packet loss ;)

Makes sense. The fact that I am new, might be an obstacle but I'll figure it out eventually. What I realised is that when I program more, I tend to think more logically.

Thank you for your explanations and have a good day!

 

Kind Regards,

Supra

Link to comment
Share on other sites

@supraaxdd Good luck! I was the same and I learned to think more logically as I programmed for longer, I guess everyone goes through that at some point in their life :)

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...