Jump to content
antmar904

Array Delimiter Help Again

Recommended Posts

antmar904

Hi,

I use a program to gain the software inventory on a remote computer and here is what the output file looks like:

==================================================
Entry Name          : 7-Zip 17.01 beta
Product Name        : 7-Zip
Version             : 17.01 beta
Company             : Igor Pavlov
Description         : 7-Zip File Manager
Obsolete            : No
Uninstall           : Yes
Installation Folder : C:\Program Files\7-Zip\
Install Source      : 
Web Site            : 
Installation Date   : 11/15/2017 1:20:09 PM
Uninstall String    : C:\Program Files\7-Zip\Uninstall.exe
Installation Change String: 
Quiet Uninstall     : No
Registry Key        : 7-Zip
Installer           : Unknown
Root Key            : HKEY_LOCAL_MACHINE
System Component    : No
==================================================

==================================================
Entry Name          : ACI Reciprocating Compressor Model
Product Name        : 
Version             : 1.0.0.0
Company             : 
Description         : 
Obsolete            : No
Uninstall           : Yes
Installation Folder : 
Install Source      : C:\Users\usa\Downloads\
Web Site            : 
Installation Date   : 10/2/2015 7:52:14 AM
Uninstall String    : MsiExec.exe /X{7A97835D-FAF8-4007-886E-B937EECE21FB}
Installation Change String: MsiExec.exe /I{7A97835D-FAF8-4007-886E-B937EECE21FB}
Quiet Uninstall     : No
Registry Key        : {7A97835D-FAF8-4007-886E-B937EECE21FB}
Installer           : Windows Installer
Root Key            : HKEY_LOCAL_MACHINE
System Component    : No
==================================================

==================================================
Entry Name          : Adobe Acrobat Reader DC
Product Name        : 
Version             : 18.009.20044
Company             : Adobe Systems Incorporated
Description         : 
Obsolete            : No
Uninstall           : Yes
Installation Folder : C:\Program Files\Adobe\Acrobat Reader DC\
Install Source      : C:\Windows\MSICACHE\AcroRdDC\
Web Site            : http://www.adobe.com
Installation Date   : 11/28/2017 2:23:51 PM
Uninstall String    : MsiExec.exe /X{AC76BA86-7AD7-1033-7B44-AC0F074E4100}
Installation Change String: MsiExec.exe /I{AC76BA86-7AD7-1033-7B44-AC0F074E4100}
Quiet Uninstall     : No
Registry Key        : {AC76BA86-7AD7-1033-7B44-AC0F074E4100}
Installer           : Windows Installer
Root Key            : HKEY_LOCAL_MACHINE
System Component    : No
==================================================

I would like to add this info into an array and display it in a listview box.

I'm having issues reading this file and adding it into a 2D array with ":" as the delimiter.

#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>

AppList()

Func AppList()
    Local $aRetArray, $sFilePath = @ScriptDir & "\Inv\log.log"
    _FileReadToArray($sFilePath, $aRetArray, Default, ":")
    _ArrayDisplay($aRetArray, "AppList")
EndFunc

 

Share this post


Link to post
Share on other sites
antmar904
1 minute ago, Jos said:

So why did you post this in the examples forum?

Jos

That was by accident, how do I move it?

Share this post


Link to post
Share on other sites
antmar904

I'm not sure how to specify the delimiter <space> and a semicolon ":".

Exp Test:

Entry Name          : Adobe Acrobat Reader DC

Share this post


Link to post
Share on other sites
benners

From the help file

Quote

If the delimiter is more than a single character then the $FRTA_ENTIRESPLIT flag setting determines the split method.

so the code would have to be

#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>

AppList()

Func AppList()
    Local $aRetArray, $sFilePath = @ScriptDir & "\Inv\log.log"
    _FileReadToArray($sFilePath, $aRetArray, $FRTA_ENTIRESPLIT, ": ")
    _ArrayDisplay($aRetArray, "AppList")
EndFunc

The problem will be the lines that don't contain the delimiter. The lines will have different numbers of fields and _FileReadToArray will error out. You'll have to remove the lines or use $FRTA_INTARRAYS as well as $FRTA_ENTIRESPLIT and go from there.

Share this post


Link to post
Share on other sites
kylomas

antmar904,

Try this...note the comments in the code...

#include <Array.au3>
#include <file.au3>

Local $afile

_FileReadToArray(@ScriptDir & '\invlog.log', $afile) ;  your first split is on the eol char, not the colon
Local $aFinal[UBound($afile)][2] ;  your result array sized from the array created from _FileReadToArray

Local $idx = 0 ; keep track of array row

For $i = 1 To UBound($afile) - 1
    If StringLeft($afile[$i], 1) = '=' Or StringLeft($afile[$i], 1) = '' Then ContinueLoop
    $aFinal[$idx][0] = StringStripWS(StringRegExpReplace($afile[$i], '([^:]+):.*', '$1'), 3) ; set final array elemnt 0 with data on the left side of ":'...strip leading and trailing spaces
    $aFinal[$idx][1] = StringStripWS(StringRegExpReplace($afile[$i], '.*:(.*)', '$1'), 3) ; set final array elemnt 1 with data on the right side of ":'...strip leading and trailing spaces
    $idx += 1
Next

ReDim $aFinal[$idx][2] ; resize array to valid entries

_ArrayDisplay($aFinal)

kylomas

Edited by kylomas
  • Like 1

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites
benners

@kylomas Gotta love StringRegExp, wish I knew how to use it better. It's cleaner than my attempt

#include <Array.au3>
#include <File.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

AppList()

Func AppList()
    Local $aRetArray = ''

    _FileReadToArray(@ScriptDir & "\Inv\log.log", $aRetArray)

    Local $as_New[$aRetArray[0]][2]
    Local $as_Temp = ''
    Local $i_Row = 0

    For $i = 1 To $aRetArray[0] ; loop through the file read array
        If Not StringInStr($aRetArray[$i], ': ') Then ContinueLoop ; skip strings with no delimiter

        $as_Temp = StringSplit($aRetArray[$i], ": ", $STR_ENTIRESPLIT) ; Split the 1D elements using the delimiter

        For $j = 0 To UBound($as_New, 2) - 1 ; loop through the split string array
            $as_New[$i_Row][$j] = $as_Temp[$j + 1] ; Get the elements into the 2D array
        Next

        $i_Row += 1 ; increase the array row count
    Next

    ReDim $as_New[$i_Row][2] ; resize the array

    GUICreate("AppList", 400, 500) ; Create GUI
    Local $id_Listview = GUICtrlCreateListView("", 2, 2, 394, 495)

    ; Add columns
    _GUICtrlListView_AddColumn($id_Listview, "Items", 150)
    _GUICtrlListView_AddColumn($id_Listview, 'Values', 220)

    _GUICtrlListView_SetItemCount($id_Listview, $i_Row) ; set the number of listview items
    _GUICtrlListView_AddArray($id_Listview, $as_New) ; load the list view

    GUISetState(@SW_SHOW)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()
EndFunc   ;==>AppList

 

Share this post


Link to post
Share on other sites
benners

Needed a distraction so....

#include <File.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

AppList()

Func AppList()
    Local $as_FRTA = ''
    _FileReadToArray(@ScriptDir & "\Inv\log.log", $as_FRTA)

    Local $i_Row = 0

    For $i = 1 To $as_FRTA[0] ; loop through the file read array to get the number of entries (no need for redim)
        If Not StringInStr($as_FRTA[$i], ': ') Then ContinueLoop ; skip strings with no delimiter
        $i_Row += 1 ; count how many lines have a delimiter
    Next

    Local _
            $i_TotalProperties = 18, _ ; # of properties (Entry Name  -> System Component)
            $i_Apps = ($i_Row / $i_TotalProperties), _ ; # of individual apps
            $i_Col = 1 ; starting column for the array
    Local _
            $as_AppList[$i_TotalProperties][$i_Apps + 1], _ ; array that holds the software info
            $as_Split = '' ; array that holds StringSplit

    For $i = 1 To $as_FRTA[0] ; loop through the file read array
        If Not StringInStr($as_FRTA[$i], ': ') Then ContinueLoop ; skip strings with no delimiter

        For $i_Row = 0 To $i_TotalProperties - 1 ; run through a block of 18 (# of properties)
            $as_Split = StringSplit($as_FRTA[$i], ": ", $STR_ENTIRESPLIT) ; Split the 1D elements using the delimiter

            If $i_Col = 1 Then $as_AppList[$i_Row][$i_Col - 1] = $as_Split[1] ; first run, write to the properties column as well
            $as_AppList[$i_Row][$i_Col] = $as_Split[2] ; write the values to the array

            If $i_Row = 17 Then $i_Col += 1 ; set the column to write the info to
            $i += 1 ; increase to get the next string
        Next
    Next

    GUICreate("AppList", 600, 400) ; Create GUI
    Local $id_Listview = GUICtrlCreateListView("", 2, 2, 595, 395)

    _GUICtrlListView_AddColumn($id_Listview, "Properties", 150)

    For $i = 1 To $i_Apps
        _GUICtrlListView_AddColumn($id_Listview, 'Application ' & $i, 350) ; create columns for app info
    Next

    _GUICtrlListView_SetItemCount($id_Listview, $i_TotalProperties) ; set the number of listview items
    _GUICtrlListView_AddArray($id_Listview, $as_AppList) ; load the list view

    GUISetState(@SW_SHOW)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()
EndFunc   ;==>AppList

Using Kylomas' StringRegExpReplace instead of  using StringSplit.

Had to alter the pattern a bit to stop it messing with the file paths and http strings 

'.*:(.*)'

to

'.*: (.*)'
#include <File.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

AppList()

Func AppList()
    Local $as_FRTA = ''
    _FileReadToArray(@ScriptDir & "\Inv\log.log", $as_FRTA)

    Local $i_Row = 0

    For $i = 1 To $as_FRTA[0] ; loop through the file read array to get the number of entries (no need for redim)
        If Not StringInStr($as_FRTA[$i], ': ') Then ContinueLoop ; skip strings with no delimiter
        $i_Row += 1 ; count how many lines have a delimiter
    Next

    Local _
            $i_TotalProperties = 18, _ ; # of properties (Entry Name  -> System Component)
            $i_Apps = ($i_Row / $i_TotalProperties), _ ; # of individual apps
            $i_Col = 1 ; starting column for the array
    Local _
            $as_AppList[$i_TotalProperties][$i_Apps + 1] ; array that holds the software info

    For $i = 1 To $as_FRTA[0] ; loop through the file read array
        If Not StringInStr($as_FRTA[$i], ': ') Then ContinueLoop ; skip strings with no delimiter

        For $i_Row = 0 To $i_TotalProperties - 1 ; run through a block of 18 (# of properties
            If $i_Col = 1 Then $as_AppList[$i_Row][$i_Col - 1] = StringStripWS(StringRegExpReplace($as_FRTA[$i], '([^:]+):.*', '$1'), 3) ; first run, write to the properties column as well
            $as_AppList[$i_Row][$i_Col] = StringStripWS(StringRegExpReplace($as_FRTA[$i], '.*: (.*)', '$1'), 3) ; write the values to the array

            If $i_Row = 17 Then $i_Col += 1 ; set the column to write the info to
            $i += 1 ; increase to get the next string
        Next
    Next

    GUICreate("AppList", 600, 400) ; Create GUI
    Local $id_Listview = GUICtrlCreateListView("", 2, 2, 595, 395)

    _GUICtrlListView_AddColumn($id_Listview, "Properties", 150)

    For $i = 1 To $i_Apps
        _GUICtrlListView_AddColumn($id_Listview, 'Application ' & $i, 350) ; create columns for app info
    Next

    _GUICtrlListView_SetItemCount($id_Listview, $i_TotalProperties) ; set the number of listview items
    _GUICtrlListView_AddArray($id_Listview, $as_AppList) ; load the list view

    GUISetState(@SW_SHOW)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()
EndFunc   ;==>AppList

 

Edited by benners
Tweaking

Share this post


Link to post
Share on other sites
antmar904
3 hours ago, benners said:

Needed a distraction so....

#include <File.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

AppList()

Func AppList()
    Local $as_FRTA = ''
    _FileReadToArray(@ScriptDir & "\Inv\log.log", $as_FRTA)

    Local $i_Row = 0

    For $i = 1 To $as_FRTA[0] ; loop through the file read array to get the number of entries (no need for redim)
        If Not StringInStr($as_FRTA[$i], ': ') Then ContinueLoop ; skip strings with no delimiter
        $i_Row += 1 ; count how many lines have a delimiter
    Next

    Local _
            $i_TotalProperties = 18, _ ; # of properties (Entry Name  -> System Component)
            $i_Apps = ($i_Row / $i_TotalProperties), _ ; # of individual apps
            $i_Col = 1 ; starting column for the array
    Local _
            $as_AppList[$i_TotalProperties][$i_Apps + 1], _ ; array that holds the software info
            $as_Split = '' ; array that holds StringSplit

    For $i = 1 To $as_FRTA[0] ; loop through the file read array
        If Not StringInStr($as_FRTA[$i], ': ') Then ContinueLoop ; skip strings with no delimiter

        For $i_Row = 0 To $i_TotalProperties - 1 ; run through a block of 18 (# of properties)
            $as_Split = StringSplit($as_FRTA[$i], ": ", $STR_ENTIRESPLIT) ; Split the 1D elements using the delimiter

            If $i_Col = 1 Then $as_AppList[$i_Row][$i_Col - 1] = $as_Split[1] ; first run, write to the properties column as well
            $as_AppList[$i_Row][$i_Col] = $as_Split[2] ; write the values to the array

            If $i_Row = 17 Then $i_Col += 1 ; set the column to write the info to
            $i += 1 ; increase to get the next string
        Next
    Next

    GUICreate("AppList", 600, 400) ; Create GUI
    Local $id_Listview = GUICtrlCreateListView("", 2, 2, 595, 395)

    _GUICtrlListView_AddColumn($id_Listview, "Properties", 150)

    For $i = 1 To $i_Apps
        _GUICtrlListView_AddColumn($id_Listview, 'Application ' & $i, 350) ; create columns for app info
    Next

    _GUICtrlListView_SetItemCount($id_Listview, $i_TotalProperties) ; set the number of listview items
    _GUICtrlListView_AddArray($id_Listview, $as_AppList) ; load the list view

    GUISetState(@SW_SHOW)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()
EndFunc   ;==>AppList

Using Kylomas' StringRegExpReplace instead of  using StringSplit.

Had to alter the pattern a bit to stop it messing with the file paths and http strings 

'.*:(.*)'

to

'.*: (.*)'
#include <File.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

AppList()

Func AppList()
    Local $as_FRTA = ''
    _FileReadToArray(@ScriptDir & "\Inv\log.log", $as_FRTA)

    Local $i_Row = 0

    For $i = 1 To $as_FRTA[0] ; loop through the file read array to get the number of entries (no need for redim)
        If Not StringInStr($as_FRTA[$i], ': ') Then ContinueLoop ; skip strings with no delimiter
        $i_Row += 1 ; count how many lines have a delimiter
    Next

    Local _
            $i_TotalProperties = 18, _ ; # of properties (Entry Name  -> System Component)
            $i_Apps = ($i_Row / $i_TotalProperties), _ ; # of individual apps
            $i_Col = 1 ; starting column for the array
    Local _
            $as_AppList[$i_TotalProperties][$i_Apps + 1] ; array that holds the software info

    For $i = 1 To $as_FRTA[0] ; loop through the file read array
        If Not StringInStr($as_FRTA[$i], ': ') Then ContinueLoop ; skip strings with no delimiter

        For $i_Row = 0 To $i_TotalProperties - 1 ; run through a block of 18 (# of properties
            If $i_Col = 1 Then $as_AppList[$i_Row][$i_Col - 1] = StringStripWS(StringRegExpReplace($as_FRTA[$i], '([^:]+):.*', '$1'), 3) ; first run, write to the properties column as well
            $as_AppList[$i_Row][$i_Col] = StringStripWS(StringRegExpReplace($as_FRTA[$i], '.*: (.*)', '$1'), 3) ; write the values to the array

            If $i_Row = 17 Then $i_Col += 1 ; set the column to write the info to
            $i += 1 ; increase to get the next string
        Next
    Next

    GUICreate("AppList", 600, 400) ; Create GUI
    Local $id_Listview = GUICtrlCreateListView("", 2, 2, 595, 395)

    _GUICtrlListView_AddColumn($id_Listview, "Properties", 150)

    For $i = 1 To $i_Apps
        _GUICtrlListView_AddColumn($id_Listview, 'Application ' & $i, 350) ; create columns for app info
    Next

    _GUICtrlListView_SetItemCount($id_Listview, $i_TotalProperties) ; set the number of listview items
    _GUICtrlListView_AddArray($id_Listview, $as_AppList) ; load the list view

    GUISetState(@SW_SHOW)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()
EndFunc   ;==>AppList

 

Thank you all for your help on this.

How would I list all the applications and their details in one column instead of creating a new column for each application?

Share this post


Link to post
Share on other sites
benners

See post #6 or #7

Share this post


Link to post
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

×