Working with Multiple Arrays

Hello,

I’m trying to figure out how I can build a new array using values from $arrFullNames if it contains the value in $arrOldNames.

$arrFullNames = @(Get-Content '\\mynas\ar_books\full_names.txt')
$arrOldNames = @(Get-Content '\\mynas\ar_books\old_names_5.txt')

Note:
$arrOldNames contains only a list of old folder names like so: old_name_1
$arrFullNames contains the full path and folder name like so: ‘\\mynas\ar_books\old_name_1

For example, if ‘old_name_1’ is contained in $arrFullNames, then store that value from $arrFullNames into a new array called $arrOldNames2.

I can use the following to check if the $oldName exists in $arrFullNames

foreach ($oldName in $arrOldNames) {
  if ($arrFullNames -like "*$oldName*") {
    Write-Host "$oldName exists"
  }
}

However, I can’t figure out how to retrieve the object in $arrFullNames to store it into a new array.

Any help would be greatly appreciated. Thanks…

I think I just found something that will help me achieve my final goal with renaming the folders…
I just need to test it out more to perform the actual renaming…

foreach ($oldName in 0..$arrOldNames.GetUpperBound(0)) {
  if ($arrFullNames -like "*$oldName*") {
    Write-Output "Full OLD name is $($arrFullNames[$line])"
    #Write-Output "OLD name is $($arrOldNames[$line])"
    Write-Output "NEW name is $($arrNewNames[$line])"
    #Write-Host "$oldName exists"
  }
}

I’ll be back… :wink:

DISREGARD… that GetUpperBound(0) isn’t returning the correct NewName value I wanted… The Write-Output "Full OLD name is $($arrFullNames[$line])" is returning the first value in that array, not the one it’s being matched to.
This is why I think I need the new array so that the new array will line up with the NewName array…
If there’s a way to search and rename without a new array, that would be optimal…

If I am understanding you properly, this might be what you’re looking for:

EDIT to code that actually works:

$arrFullNames = @(Get-Content '\\mynas\ar_books\full_names.txt')
$arrOldNames = @(Get-Content '\\mynas\ar_books\old_names_5.txt')

$arr = $arrFullNames | Where-Object {
    $arrOldNames -contains ($_ | Split-Path -Leaf)
    }
}

That code just pulls the data from the text files in, loops through each $arrfullnames object, and if it is in $arroldnames, it puts it in the output… I’m just capturing all that in the $arr var, so assuming its more than one, it will be an array of strings. In any case, the hits should be in $arr. You can name it whatever you want of course, my brain couldn’t come up w/ a name haha. If I misunderstood though sorry :smiley: I may just need further clarification on the ask.

I was trying SO hard to beat @dotnVo to the solution! lol!

This is the way I did it:

$arroldNames = @(Get-Content -path C:\temp\OldNames.txt)
$arrMatch = @()

$arroldNames | ForEach-Object {
    $name = $_
    $arrMatch += $arrFullNames | Where-Object {$_ -Like "*$name"}
}

$arrMatch

Both ways should give you same output. Mine could be simplified a little, but that just reflects the way my mind works. I didn’t think of looping through the array that already contained the data I needed to export, so I had to come up with a way for my comparison to return the matched value. Using -like in an if statement won’t do it, but that’s what Where-Object is made for.

Just shows the diversity of the language…

Hi @dotnVo
Thanks for your help with this.

I was playing around with your code, but $arr is coming up empty.
I tried the following:

  • Changed -contains to -like; still empty.
  • Reversed arrays for both tests with -contains and -like; still empty.
  • Used wildcards (*) for both tests with -contains and -like; $arrFullNames -like "*$_*" returned the 5 values from the $arrOldNames instead of the matching values from the $arrFullNames array.

Just curious, but is the current PS Object ($_) the array for the one being piped to the ForEach-Object or the IF statement?

Ultimately I’m trying to return the matching value from $arrFullNames array based on the search value used from the $arrOldNames array.

Something along the lines of:
if value in $arrOldName is found in $arrFullNames, then return the value found in $arrFullNames.

I’m using a wildcards because if the $arrOldNames value is: ‘old name 1’, the value in $arrFullNames will be slightly different and includes the full path to the folder; example:
\\mynas\ar_books\old name 1 - LG 3.1

I’m going to play around with @masterofthehat 's code in the time being…

Thanks again.

I got a chance to test your code and the $arrMatch was populated with the correct matching value from the $arrFullNames array.

I gotta run, but when I get back I’ll update you on my progress with renaming the folders using the values in $arrNewNames.

Figured out why mine didn’t work for you: I didn’t see that the second var was a full path, my bad :slight_smile:

EDIT: i did modify my code above so it should work now, just so its actually functioning, but it’s mostly just aligning with what Matt did

Something like this should work:

$arrNew = $arrFullNames | Where-Object {
    $arrOldNames -contains ($_ | Split-Path -Leaf)
}

Ha! yea this is what I should have done. Split-Path is an awesome little cmdlet.

UPDATE:

Hi masterofthehat,

Your solution works perfectly. I was able to test it again and use the new array it created to rename my 5 test folders.

I’ll likely use matt’s - more compact - code which produces the exact same results. I wish we could mark two solutions…? :slight_smile:

My code so far with the help from you, @dotnVo & @matt-bloomfield

Thanks to all of you and best regards…

# Arrays
$arrFullNames = @(Get-Content '\\mynas\ar_books\full_names.txt')
$arrOldNames = @(Get-Content '\\mynas\ar_books\old_names_5.txt')
$arrNewNames = @(Get-Content '\\mynas\ar_books\new_names_5.txt')

# Match OldName to FullName (matt-bloomfield)
$arrNew = $arrFullNames | Where-Object {
   $arrOldNames -contains ($_ | Split-Path -Leaf)
}

# Rename FullName (arrNew) with NewName (folder)
for ($i = 0; $i -lt $arrNew.Count; $i++) {
   Rename-Item $arrNew[$i] $arrNewNames[$i]
}

Glad it works for you!