Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/22/2024 in all areas

  1. Introduction In AutoIt, we often have to deal with data structured like tables. Depending on the source, we sometimes have to write a lot of code to convert the data into a form that we can continue working with. Subsequently, working with this data is not necessarily any easier, as instead of accessing the descriptive names of the data attributes, we have to deal with numerical indices where it is very easy to lose track. Both problems are addressed by the UDF. In the basic approach, the UDF works with a table object (just an AutoIt map) in which the data is separated from the header. This enables cleaner processing of the data. It offers functions to read in data from various sources (CSV, array, string with fixed-width-columns, strings with their own column separators). Within this call, the data is separated from the header or header data is added to it in the first place. The data is then processed according to its format (with csv quotes and escapes removed, with fixed-width spaces removed...). In addition, the user can define how exactly the data should be processed for each column individually. He is completely free to do this. In this way, the data is already given the final format in which it is to be further processed when it is read in. The data can then be handled on a column-based or attribute-based basis. In other words, instead of using indices, the attribute names of the data can simply be used - this makes the code clearer. Example (much more examples provided >>here<<) We want to evaluate the open ports on a computer with AutoIt. The command line command for this is netstat -t and gives us the following output (Depending on the system, the output may look slightly different for you): Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 116 192.168.64.110:ssh 192.168.29.200:65069 ESTABLISHED tcp 0 0 192.168.64.110:ssh 192.168.29.200:65068 ESTABLISHED To continue processing the data in a meaningful way, we may need to carry out the following steps in AutoIt: Delete the first useless lines Extract the header row (it is treated differently from the data) Create an array with the correct dimension to hold the data Separate the data either by spaces or by fixed column widths Removal of unnecessary spaces from the data Converting the Recv-Q and Send-Q column to a numeric data type (for sorting etc.) Separation of address data into IP address and port This can mean a lot of (error-prone) code effort. With this UDF, however, you can solve the whole thing in a single call as follows: $sString = 'Active Internet connections (w/o servers)' & @CRLF & _ '' & @CRLF & _ 'Proto Recv-Q Send-Q Local Address Foreign Address State' & @CRLF & _ 'tcp 0 116 192.168.64.110:ssh 192.168.29.200:65069 ESTABLISHED' & @CRLF & _ 'tcp 0 0 192.168.64.110:ssh 192.168.29.200:65068 ESTABLISHED' ; Transfer data to table type by using the size of every column: Global $mData = _td_fromFixWidth($sString, _ "left 6; Number 7; Number 7; StringSplit($x, ':', 2) 24;StringSplit($x, ':', 2) 24;", _ ; column definitions "1-2", _ ; skip row 1 to 2 True) ; display data _td_display($mData) and we get the result: If you now use functions such as _td_toObjects(), you can process the individual data with expressions such as $aData.Proto or $aData.State. This should be much clearer than having to deal with array indices. Functions >>sourcecode and download on github<<
    4 points
  2. So this should work: ; Just year -> change up Local $sExpr1 = '\data\config6_2023_full.data' ConsoleWrite($sExpr1 & @TAB & ' --->>> ' & ProcessDate($sExpr1, True) & @CRLF) ; Year and month -> change down Local $sExpr2 = '\data\config6_202305_full.data' ConsoleWrite($sExpr2 & @TAB & ' --->>> ' & ProcessDate($sExpr2, False) & @CRLF) ; Year and month -> change up Local $sExpr3 = '\data\config6_20230511_full.data' ConsoleWrite($sExpr3 & @TAB & ' --->>> ' & ProcessDate($sExpr3, True) & @CRLF) Func ProcessDate($sExpr, $bUp) Local $aRegEx = StringRegExp($sExpr, '^(?:.*?)(\d{4})(?:(\d{2}){0,1})(?:(\d{2}){0,1})(?:.*?)$', 3) If IsArray($aRegEx) Then Switch UBound($aRegEx) Case 1 Return String(Int($aRegEx[0]) + ($bUp ? 1 : -1)) Case 2 Return $aRegEx[0] & (StringLen(Int($aRegEx[1])) = 1 ? '0' : '') & String(Int($aRegEx[1]) + ($bUp ? 1 : -1)) Case 3 Return $aRegEx[0] & $aRegEx[1] & ((StringLen(Int($aRegEx[2])) = 1 ? '0' : '') & String(Int($aRegEx[2]) + ($bUp ? 1 : -1))) EndSwitch EndIf EndFunc You should be able to add a little bit more logic in this function for cases when month it's 12 and user want to go up so you don't result in invalid date. But this is beyond the scope since you are here for regex, right?
    1 point
×
×
  • Create New...