Merrill Cook
Merrill Cook

Reputation: 1208

How to save select-string output from bulk text files to an array powershell

I am trying to pull substrings out of text files in bulk saving these substrings to an array. I have tried variations of the following. This outputs all of the selected strings to the screen but only saves the final output to the variable. Is there a way to mimic the functionality of a =+ operator in outvariable so that all items get stored in an array?

$FILES = ls "*.txt"
foreach($f in $FILES){
  $in=Get-Content $f
  $in | Foreach { Select-String -Path "$f" -Pattern "Ad ID" -outvariable 
  array1 }}

In the event that my strategy is misguided, the overall purpose of pulling substrings into an array is to have several arrays of separate substrings of these text files. Then I will concatenate the values into a csv. I'm attempting to pull elements out rather than re-arrange the text files as substrings within the text files are in different order. Example:

Txt File One:

Ad Id: xxxx
Ad Text: blah blah
Ad placement: spaceship

Txt File Two:

Ad Id: yyyy
Ad placement: zoo
Ad Text: blah blah

Final desired result (this part is working except for the order of the elements)

CSV file

xxxx, spaceship, blah blah
yyyy, zoo, blah blah

Upvotes: 1

Views: 5881

Answers (3)

user6811411
user6811411

Reputation:

Another slightly different approach.

  • A RegEx parses $Line and creates a variable with the name before the colon (without Ad) and value what is behind
  • After each processed file the vars are output as a custom object

$Data = ForEach ($File in (Get-ChildItem File*.txt)){
    $Id,$Text,$Placement="","",""
    ForEach ($Line in (Get-Content $File)){
        If ($Line -Match "AD (?<Label>.*?): (?<Value>.*)"){
            Set-Variable -Name "$($Matches.Label)" -Value $Matches.Value
        }
    }
    [PSCustomObject]@{ID        = $Id
                      Placement = $placement
                      Text      = $Text}
}
$Data
$Data | Export-CSv ".\Result.csv" -NoTypeInformation

Sample output:

ID   Placement Text
--   --------- ----
xxxx spaceship blah blah
yyyy zoo       blah blah

Upvotes: 1

f6a4
f6a4

Reputation: 1782

Try this one:

$files      = ls "*.txt"
$dictionary = @{}

foreach($f in $files) {
    $in = Get-Content $f
    $in.Split([Environment]::NewLine) | ForEach-Object {
        $key,$value = $_.Split(':')
        $dictionary[$key] = $value
    }
    $dictionary['Ad Id'] + ', ' + $dictionary['Ad placement'] + ', ' + $dictionary['Ad Text'] | Out-File -FilePath '.\results.csv' -Append
}

Sorted output:

$files      = ls "fil*.txt"
$dictionary = @{}
[System.Collections.Generic.List[String]]$list = @()

foreach($f in $files) {
    $in = Get-Content $f
    $in.Split([Environment]::NewLine) | ForEach-Object {
        $key,$value = $_.Split(':')
        $dictionary[$key] = $value
    }
    [void]$list.Add( $dictionary['Ad Id'] + ', ' + $dictionary['Ad placement'] + ', ' + $dictionary['Ad Text'] )
}
[void]$list.Sort()
$list | Out-File -FilePath '.\results.csv' -Append

Upvotes: 1

lit
lit

Reputation: 16236

Here is a way to build the array you are talking about. I do not think this is the best way to solve this problem. This does nothing about the order of results, nor does it create a .csv file.

$FILES = Get-ChildItem -File -Filter "*.txt"

$array1 = $()

foreach($f in $FILES) {
    Get-Content -Path $f |
        Select-String -Pattern "Ad Id.*" |
        ForEach-Object { $array1 += @($_.Matches.Value) }
}

$FILES.Count

$array1.Count
$array1

Upvotes: 2

Related Questions