How to store information from the Select function in a variable

Problem Statement : I have a set of files that I want to edit based on input (composite key) i want to feed in through a csv file. The composite key is made up of four parts, the first 3 are staying the same and i want to bulk edit the last field. So i am searching with the unique identifier, the ID_Device : 7x2-c-2 in Case A. The desired script identifies the exact seq and replaces the old point with the new point.

Supporting docs: strs_points-input file, sample 1-file to be edited, sample 2-file to be edited

Code:

$ID_Substn = @{}
$ID_Devtyp = @{}
$ID_Device = @{}
$ID_Point  = @{}
# Composite Key parts.


$Input = Import-CSV -Path C:\Users\e076200\Desktop\Mapping_files\strs_points.csv 
#  Retrieves input csv



$ID_Substn = $Input.SUBSTN
$ID_Devtyp = $Input.DEVTYP
$ID_Device = $Input.DEVICE
$ID_Point  = $Input.POINT
# Columns assigned.


 foreach($_ID_Device in $ID_Device)
{

  $_ID_Device


  dir "C:\Users\e076200\Desktop\Display Build" -Recurse -File | 
  
  Select-String -Pattern $_ID_Device 

# Recurse function applied with $_ID_Device.
  }

So far I have been able to find ‘id_device’ so I am trying to figure out how to store the file name, line and line number of where i am, so i can make reference to it in the console. I have only been able to get it on a csv by piping in the command below:

Select Filename, path, LineNumber, Line | Add-Content “C:\Users\e076200\Desktop\Mapping_files\Out.csv”

Chudi,
Welcome to the forum. :wave:t4:

Before we proceed … When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org <---- Click :point_up_2:t4: :wink:

Reading your question I’m pretty unsure what you’re actually trying to do. You may elaborate a littel more detailed about what the task is about - not the way you think you have to go to achieve the task. :wink:

You may share a few sanitized lines of your input CSV file as well (formatted as code as well). It may help understanding your issue.

And BTW: what means CK parts.?

Hi Olaf,

Please let me know if it makes sense now lol.

The formatting of the code is great. :+1:t4:

But the code itself actually does not make that much sense. Sorry. :man_shrugging:t4:

Since

can take multiple patterns at once you don’t need a loop. So this should be enough actually:

$InputCSV = Import-CSV -Path C:\Users\e076200\Desktop\Mapping_files\strs_points.csv 
Get-ChildItem "C:\Users\e076200\Desktop\Display Build" -Recurse -File | 
    Select-String -Pattern $InputCSV.DEVICE

I just don’t know yet what you want to do with the results. And the images you shared do not show this either. And BTW: do not post images of code or sample data since this is not helpful. If I wanted to use this for tests I’d need to type all this. Instead post the plain text and format it as code.

You may post an example of the desired output as well to show what you want to achieve.

Ah, I see, that makes sense. I will scratch the for loop.

Yeah, it didn’t allow me upload the txt files, hence the screen shot but i see why that was a bad idea.

I want to update a specific field (point) for multiple records in multiple files in a directory. The csv file is a table of the records to be updated so the desired outcome is to find the exact match and update the last field(point) in the txt files directly.

#Sample 1 . Pattern of record in text file to be found:

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("7X2-C-2") 
					record("POINT") record_key("3PS") 
					)

Desired output:

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("7X2-C-2") 
					record("POINT") record_key("STRS") 
					)

#Sample 2 . Pattern of record in text file to be found:

picture "CT_CB_V" 
			(
				set("CT_") 
				origin(513 1177) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("18P3-C-2") 
					record("POINT") record_key("4JY") 
				)

Desired output:

picture "CT_CB_V" 
			(
				set("CT_") 
				origin(513 1177) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("18P3-C-2") 
					record("POINT") record_key("STRS") 

				)

Input CSV :
SUBSTN | DEVTYP |   DEVICE   | OLD_POINT | NEW_POINT
  7X       CB      7X2-C-2        3PS          STRS
  18P      CB      18P3-C-2       4JY          STRS

That might be a little too early … this tipp was based just on the code I saw - not on your task I didn’t understand yet. :wink:

Is it by coincidence or do you always want to replace the pattern you find with “STRS”? That would make the code way easier … like this:

 Get-ChildItem -Path 'C:\Users\e076200\Desktop\Display Build' |
    ForEach-Object {
        $OldContent = Get-Content -Path $_.FullName -Raw
        $NewContent = $OldContent -replace '(?<=record\("POINT"\)\ record_key\(").+(?="\))', 'STRS'
        $NewContent | Out-File -FilePath $_.FullName
    }

If that does not help and depending on the amount of data you want to process and if all of the files you have in "C:\Users\e076200\Desktop\Display Build" will probably have a pattern to replace you may use another approach.

So could you please share some more detailed information about your task? Please keep in mind - we cannot see your screen and we cannot read your mind. And please make it as less hard to help you as possible. Post code separated from sample data and sample data from different files in separate chunks and use the original format of your sample data (CSV). :wink:

I need it to check for the full composite key in my input file because there are other records in the files, i am trying to update, that should not be changed. The update is no always “STRS”. New_point column contains the updated record

Each file will look something like this:

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("18P3-C-2") 
					record("POINT") record_key("4JY") 
					)

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CF") 
					record("DEVICE") record_key("7X4-C-2") 
					record("POINT") record_key("3PS") 
					)

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("AB") 
					record("DEVICE") record_key("7-V-2") 
					record("POINT") record_key("3PS") 
					)


picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("49A-2") 
					record("POINT") record_key("3PS") 
					)

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("7X2-C-2") 
					record("POINT") record_key("3PS") 
					)

In this case I only want to replace the point record of the first and last device. That is essentially the task for multiple files.

What i am trying to do is pass the csv file in. Split the columns into 4 placeholders. Use the unique identifier which is the device field ( 3rd field, which holds the name of the device) for the first loop, and then do a match for the SUBSTN record and DEVTYP, if those two conditions are met then change the point record to new point (csv file). Again the csv looks like this. Posting it two ways, no sure which is better.

|SUBSTN|DEVTYP|DEVICE|NEW_POINT|OLD_POINT|
|---|---|---|---|---|
|'7X'|CB|7X2-C-2|STRS|3PS|
|'18P'|CB|18P3-C-2|XAS|4JY|

SUBSTN DEVTYP DEVICE NEW_POINT OLD_POINT
‘7X’ CB 7X2-C-2 STRS 3PS
‘18P’ CB 18P3-C-2 XAS 4JY

You are really giving me a hard time. :smirk:

When you open your CSV file with a text editor or with VSCode - does it look something like you shared before? Or does it actually look something like this?

SUBSTN,DEVTYP,DEVICE,NEW_POINT,OLD_POINT
'7X',CB,7X2-C-2,STRS,3PS
'18P',CB,18P3-C-2,XAS,4JY

This way I can copy it and use it as it is … :man_shrugging:t4:

The file content you shared … is it all in one file or are they individual files like this:
sample File 1:

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("18P3-C-2") 
					record("POINT") record_key("4JY") 
					)

sample file 2

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CF") 
					record("DEVICE") record_key("7X4-C-2") 
					record("POINT") record_key("3PS") 
					)

???

Input file - CSV file looks like this :

SUBSTN,DEVTYP,DEVICE,NEW_POINT,OLD_POINT
‘7X’,CB,7X2-C-2,STRS,3PS
‘18P’,CB,18P3-C-2,XAS,4JY

File to be edited - Each file contains a series of devices so each file looks like this :

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("18P3-C-2") 
					record("POINT") record_key("4JY") 
					)

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CF") 
					record("DEVICE") record_key("7X4-C-2") 
					record("POINT") record_key("3PS") 
					)

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("AB") 
					record("DEVICE") record_key("7-V-2") 
					record("POINT") record_key("3PS") 
					)


picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("49A-2") 
					record("POINT") record_key("3PS") 
					)

picture "CT_CB_H" 
			(
				set("CT_") 
				origin(154 587) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("7X2-C-2") 
					record("POINT") record_key("3PS") 
					)

There might be a more sophisticated way but for the given information and sample data it works …

I assume the CSV input file name is CSV_Input.csv and the file with the sample data is sample_Data.txt.

$CSVData = Import-Csv -Path .\CSV_Input.csv

$SampleData = Get-Content -Path .\sample_Data.txt -Raw 
$splitarray = $SampleData -split '(?=picture "CT_CB_H")' | Select-Object -Skip 1

for ($i = 0; $i -lt $splitarray.Count; $i++) {
    foreach ($element in $CSVData) {
        $DEVTYP = 'record("DEVTYP") record_key("{0}")' -f $element.DEVTYP
        $DEVICE = 'record("DEVICE") record_key("{0}")' -f $element.DEVICE 
        $POINT = 'record("POINT") record_key("{0}")' -f $element.OLD_POINT

        $PatternList = 
        [regex]::escape($DEVTYP),
        [regex]::escape($DEVICE),
        [regex]::escape($POINT)
        $Result = 
        foreach ($Pattern in $PatternList) {
            Select-String -InputObject $splitarray[$i] -Pattern $Pattern -Quiet
        }
        if ($Result.count -eq 3) {
            $splitarray[$i] = 
                $splitarray[$i] -replace '(?<=record\("POINT"\)\ record_key\(").+(?="\))' , $element.NEW_POINT
        }
    }
}

$splitarray.trim() | Out-File -FilePath .\New_sample_Data.txt -Force

What the code does …

  • import the CSV data
  • import the sample data in raw foramt to be able to treat each section as a whole
  • split the sample data into their sections (devices?), I use a regex lookahead to be able to split the data without the split operator consuming the split pattern (skip the first because it’s always empty)
  • iterate over the resulting array
  • in each section (device) …
  • creating a nested loop for all elements of the CSV data
  • in each element of the CSV data …
  • create the search patterns based on 3 columns of the CSV data
  • check if all 3 patterns exist in the current section (device)
  • if yes - replace the existing POINT with the desired one and overwrite the original section (device)
  • output all sections (devices) into a new file

I leave it to you to wrap all this into a bigger loop to process the files you need to.

Here are some help topics about elements I’m using in the code:

Format operator -f

Split and Join Operators

about_For

REGEX Lookaround

Apologies Olaf, I did a poor mock up so i don’t think this will work. This is a better representation of the files in question:

Also the DEVICE column is the name of the device so this is the best field to filter with. The first three columns can be the same but the point column is always unique. So in my first mock up. I include both cases we want to replace in the input file. Apologies again

So first file contains -
'7X',CB,7X2-C-2,3PS 
         &&
'18P',CB1,18P3-C-2,4JY

we want - 

'7X',CB,7X2-C-2,STRS 
        &&
'18P',CB1,18P3-C-2,XAS

after the edit

In the second file, I Include the second device we want to replace the point for but with two of its other points.

So second file contains -

'18P',CB1,18P3-C-2,AMPA
               &&
'18P',CB1,18P3-C-2,AMPA
               &&
'18P',CB1,18P3-C-2,4JY

we want - 

'18P',CB1,18P3-C-2,AMPA
               &&
'18P',CB1,18P3-C-2,AMPA
               &&
'18P',CB1,18P3-C-2,XAS

after the edit



# Input.csv
SUBSTN,DEVTYP,DEVICE,NEW_POINT,OLD_POINT
'7X',CB,7X2-C-2,STRS,3PS
'18P',CB1,18P3-C-2,XAS,4JY
## File name : 7X.txt

version("WebFG 3.6.0, Builder 5.8.0.0 SP7");
	picgroup "SCADA_DISPLAY_NOTE"
	(
		bottom(0) 
		right(0) 
		primary_picture "SCADA_DISPLAY_NOTE" 
		set("CT") 
		not insert 
		not delete 
		not delete_conf 
		not copy 
		picture "SCADA_DISPLAY_NOTE" 
		(
			set("CT") 
			origin(0 0) 
		)
	);
	display "7X"
	(
		title(localize "%HOST% [%DISAPP%] %DIS% STA ADDRESS") 
		application "SCADA"
		(
			color("0,0,0") 
		)
		application "RECON"
		(
			color("0,0,0") 
		)
		color("0,0,0") 
		scale_to_fit_style(XY)
		menu_bar_item "LAYER_MENU"( 
		label(localize "Layers") 
		set("CT") ) 
		horizontal_unit(10) 
		vertical_unit(10) 
		horizontal_page(50) 
		vertical_page(50) 
		refresh(2) 
		not locked_in_viewport 
		not horizontal_scroll_bar 
		not vertical_scroll_bar 
		std_menu_bar 
		command_window 
		not on_top 
		not ret_last_tab_pnum 
		default_zoom(1.0000000) 
    	simple_layer "DEFAULT"
		(
			text 
			(
				gab "YELLOW_LARGETEXT_36" 
				set("CT") 
				origin(450 65) 
				localize "7A78"
			)
            polyline 
			(
				gab "LINE_13-8KV" 
				set("CT") 
				origin(1105 200) 
				point(1105 200) 
				point(395 0)
			)
            polyline 
			(
				gab "AGIP_RED_CUBICLE_DASH_A1" 
				set("CT") 
				origin(2800 375) 
				point(2800 375) 
				point(260 0)
			)
            polyline 
			(
				gab "LINE_13-8KV" 
				set("CT") 
				origin(1500 550) 
				point(1500 550) 
				point(260 0)
			)
            polyline 
			(
				gab "LINE_13-8KV" 
				set("CT") 
				origin(460 200) 
				point(460 200) 
				point(260 0)
			)
            polyline 
			(
				gab "AGIP_RED_CUBICLE_DASH_A1" 
				set("CT") 
				origin(2280 725) 
				point(2280 725) 
				point(260 0)                
				point(0 -175)
			)
            polyline 
			(
				gab "LINE_13-8KV" 
				set("CT") 
				origin(980 200) 
				point(980 200) 
				point(260 0)
			)
            polyline 
			(
				gab "LINE_13-8KV" 
				set("CT") 
				origin(65 200) 
				point(65 200) 
				point(395 0)
			)
            polyline 
			(
				gab "AGIP_RED_CUBICLE_DASH_A1" 
				set("CT") 
				origin(2540 200) 
				point(2540 200) 
				point(260 0)                
				point(0 175)
			)
            polyline 
			(
				gab "LINE_13-8KV" 
				set("CT") 
				origin(1625 200) 
				point(1625 200) 
				point(395 0)                
				point(0 175)
			)
            picture "CT_CB_H" 
			(
				set("CT") 
				origin(2251 356) 
				composite_key 
				(
					record("SUBSTN") record_key("7X") 
					record("DEVTYP") record_key("CB") 
					record("DEVICE") record_key("7X2-C-2") 
					record("POINT") record_key("3PS") 
				)
symbol "CT_XFMR_4-8_MISC_D" 
			(
				set("CT") 
				origin(415 457) 
			)
			symbol "CT_LINE_GAP" 
			(
				set("CT") 
				origin(454 469) 
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(452 463) 
				localize "18P-1S"
			)
			picture "CT_MAN_FUSE_DISC_10D" 
			(
				set("CT") 
				origin(146 536) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("SW") 
					record("DEVICE") record_key("18P-1H1-1") 
					record("POINT") record_key("STS") 
				)
			)
			symbol "CT_LINE_GAP" 
			(
				set("CT") 
				origin(200 481) 
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(188 477) 
				localize "18P-1H"
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(186 522) 
				localize "18P-1H1-1"
			picture "CT_ANALOG_AMP_SCANNED" 
			(
				set("CT") 
				origin(395 1073) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB1") 
					record("DEVICE") record_key("18P3-C-2") 
					record("ANALOG") record_key("4JY") 

# File name : 18P.txt
version("WebFG 3.6.0, Builder 5.8.0.0 SP4");
	
	picgroup "SCADA_DISPLAY_NOTE"
	(
		bottom(0) 
		right(0) 
		primary_picture "SCADA_DISPLAY_NOTE" 
		set("CT") 
		not insert 
		not delete 
		not delete_conf 
		not copy 
		picture "SCADA_DISPLAY_NOTE" 
		(
			set("CT") 
			origin(0 0) 
		)
	);
	
	display "ESSEX_18P"
	(
		
		title(localize "%HOST% [%DISAPP%] %DIS%") 
		
		application "SCADA"
		(
			color("0,0,0") 
		)
		application "RECON"
		(
			color("0,0,0") 
		)
		color("0,0,0") 
		scale_to_fit_style(XY)
		horizontal_unit(10) 
		vertical_unit(10) 
		horizontal_page(50) 
		vertical_page(50) 
		refresh(2) 
		not locked_in_viewport 
		not horizontal_scroll_bar 
		not vertical_scroll_bar 
		std_menu_bar 
		not command_window 
		not on_top 
		not ret_last_tab_pnum 
		default_zoom(1.0000000) 
		simple_layer "DEFAULT"
		(
			symbol "CT_XFMR_MISC_D" 
			(
				set("CT") 
				origin(634 394) 
			)
			picture "CT_MAN_FUSE_DISC_10D" 
			(
				set("CT") 
				origin(400 535) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("SW") 
					record("DEVICE") record_key("18P-1S1-1") 
					record("POINT") record_key("STS") 
				)
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(446 522) 
				localize "18P-1S1-1"
			)
			symbol "CT_XFMR_4-8_MISC_D" 
			(
				set("CT") 
				origin(415 457) 
			)
			symbol "CT_LINE_GAP" 
			(
				set("CT") 
				origin(454 469) 
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(452 463) 
				localize "18P-1S"
			)
			picture "CT_MAN_FUSE_DISC_10D" 
			(
				set("CT") 
				origin(146 536) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("SW") 
					record("DEVICE") record_key("18P-1H1-1") 
					record("POINT") record_key("STS") 
				)
			)
			symbol "CT_LINE_GAP" 
			(
				set("CT") 
				origin(200 481) 
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(188 477) 
				localize "18P-1H"
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(186 522) 
				localize "18P-1H1-1"
			)
			picture "CT_ANALOG_AMP_SCANNED" 
			(
				set("CT") 
				origin(395 1039) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB1") 
					record("DEVICE") record_key("18P3-C-2") 
					record("ANALOG") record_key("AMPA") 
				)
			)
			picture "CT_ANALOG_AMP_SCANNED" 
			(
				set("CT") 
				origin(395 1056) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB1") 
					record("DEVICE") record_key("18P3-C-2") 
					record("ANALOG") record_key("AMPB") 
				)
			)
			picture "CT_ANALOG_AMP_SCANNED" 
			(
				set("CT") 
				origin(395 1073) 
				composite_key 
				(
					record("SUBSTN") record_key("18P") 
					record("DEVTYP") record_key("CB1") 
					record("DEVICE") record_key("18P3-C-2") 
					record("ANALOG") record_key("4JY") 
				)
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(398 1056) 
				localize "B"
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(398 1073) 
				localize "C"
			)
			text 
			(
				gab "CT_STANDARD_STATIC_TEXT" 
				set("CT") 
				origin(398 1039) 
				localize "A"
			)
			symbol "BTN_POKE_4CHAR" 
			(
				set("CT") 
				origin(397 1007) 
			)

Sorry … I don’t like anymore - I’m out. It’s - AGAIN - completely unclear to me what you actually want to achieve. And you changed the initial conditions completely.

It is beyond the scope of a forum like this - or any forum - to iteratively develop a working solution for your permanently changing conditions.

Of course you’re welcome to try to use my code suggestions as inspiration and try to get your task done. And of course you’re welcome to come back if you have a specific question about a particular piece of code you wrote yourself.

Good luck.

Hello,
What I understood at first reading, was that depending on the fourth keystroke you want a different indentation for the results.
But later, you give an example where the contents of the last field is different from one case to the other.
So, I am afraid that examples can be somewhat limited in efficiency, and that if you can provide a description of the treatment, it can be clearer if you succeed determining the required level of details.