I have an array and need to mapping a string inside a file by using the array then output the matched string to a file. I tried it but when I found 2 match string in the file, in the output file only has 1 string.
$ArrayString = "Network controller TPX","Network controller SXCM", "Adapter controller CNA"
$GetFile = Get-Content .\File
foreach($string in $ArrayString ){
$GetFile | Select-String -Pattern $string | Out-File .\result.txt -Force
}
The content inside the file looks like this:
Network controller SXCM
Disable
*Enable
Admin Passwordfrom Startup Menu
*Disable
Enable
Adapter controller CNA
Disable
*Enable
Verify on every boot
*Disable
Enable
in some case the string in $ArrayString will matched 1 in the $Getfile and also matched 2 string.
Anyone can help me please. Thank you so much
CodePudding user response:
The main issue with your code is that Out-File
is inside the loop and without an -Append
switch so each loop iteration is overwriting the file. Unfortunately, even if there is no match, the file would be overwritten due to the way Out-File
was coded, seems like it opens the file stream in it's begin
block which, shouldn't be the case and is one of many reasons why Set-Content
should be the go to cmdlet when writing to a plain text file.
To explain the issue with Out-File
visually:
# Create a temp file and write some content to it:
$file = New-TemporaryFile
'content' | Set-Content $file.FullName
Get-Content $file.FullName # => content
# `Process` block doesn't run on `AutomationNull.Value`,
# so, the expected would be, if nothing is received from pipeline,
# don't touch the file:
& { } | Set-Content $file.FullName
Get-Content $file.FullName # => 'content' // as expected
# Trying the same with `Out-File`
& { } | Out-File $file.FullName
Get-Content $file.FullName # => null // file was replaced
# dispose the file after testing...
$file | Remove-Item
A few considerations, Select-String
can read files so Get-Content
is not needed, and -Pattern
can take an array of patterns to match. Here is the simplified version of your code.
$ArrayString = "Network controller TPX", "Network controller SXCM", "Adapter controller CNA"
Select-String -Path .\file.txt -Pattern $ArrayString |
ForEach-Object { $_.Matches.Value } | Set-Content result.txt