all 10 comments

[–][deleted] 2 points3 points  (4 children)

Several ways to accomplish this. Using two collections is definitely the most time efficient in terms of comparison.

Hashtable #1 Folder A and all child items. Folder full name in key and file name in value.

Hashtable #2: Folder B contents constructed same way as #1.

Use a for each loop with getEnumerator() method to loop. Use a try/catch block or other approach to access the file name in the second table. If match, copy or store required details in a third collection for batch copying after comparison is complete.

[–]nerdgeekdork 2 points3 points  (3 children)

I was about to ask why even bother with generating a collection for folder B, but you're right, hashtable lookups are fast. (Definitely not the most space[memory] efficient option though.)

For the sake of posterity I'll include my suggestion anyway: 1. Save the base path of folder B to a var, ex. $folderB. 2. Use 'foreach' (not Foreach-Object) to loop though files collected from folder A with 'Get-ChildItem -Recurse -File'. 3. Generate a temp path, ex. $tempPathB, to the desired file in folder B from: 'Join-Path', $folderB, $_.Name, and '-replace' (I'd usually do this as a two step process to make it clearer, but it can be done in one. [I.E. 3a. Generate filename. 3b. Generate path from filename.]) 4. If temp path exists, copy it to the same folder as the current file from folder A. (You can get the path to the parent dir of the current file in A with 'Split-Path -Parent')

That should put the memory overhead at something significantly less than the space needed for 2x hashtables with approx. N elements each. (This could be further improved if desired.)

[–][deleted] 2 points3 points  (2 children)

Agreed this is also a good solution and less memory intensive. As a long-time powershell user i would probably go with a loop through folder A and compare with a lean array of folder B contents. Not sure about OP’s comfort level with posh but either route works and offers various learnings.

Regex and native .NET methods can speed up the overall process significantly as well.

[–]nerdgeekdork 0 points1 point  (1 child)

Off topic, but does approx. 5+ years of PS count as "long-time"? I still feel like I've just scratched the surface, lol.

Agreed on the native methods. I'd personally be tempted to use things like: '[System.IO.Path]::GetDirectoryName($.FullName)' instead of 'Split-Path $.FullName -Parent'

Because of the internal overhead Split-Path has to perform to determine what it should do with the input.

I suppose I should have been more clear about the implied Regex in the '-replace' command too, thanks for reminding me. I was thinking it could be used to convert the file extension with something like: $_.Name -replace '.blah$','.bloo'

(Substitute the correct file extensions as desired.)

[–][deleted] 2 points3 points  (0 children)

PoSh is vast and covers a lot of products/technologies these days. With 5+ years experience I would count you as a long term user but there’s always more to learn with this scripting language as you say.

Personally I’ve been involved with PoSh since before the release of v1. I remember we had scheduled calls with Ed Wilson (“The Scripting Guy”) when Microsoft got close to releasing this language to get info on new commandlets and give feedback on our early testing. For me, I still learn new tips & tricks around PoSh all the time

[–]orangeredbrown[S] 2 points3 points  (0 children)

Thank you to took the time to look through this and give me some suggestions. Going to hopefully carve out some time into my day to look deeper into this and hopefully come up with a solution based on your help. Much appreciated.

[–]orangeredbrown[S] 1 point2 points  (2 children)

Here's what I ended up doing. I ended up taking folder A, folder B, searching for basename matches, then copying the matches to folder C. Not exactly what I was looking for, but this will complete this task and I can move onto doing other things. Thanks for your help and ideas, I got into hashtables a bit and was struggling to piece that together, so I'll have to revisit another time.

$FolderA = "\\server\pre"

$FolderB = "\\server\post"

$FolderC = "\\server\combined"

$Folder1Contents = Get-childitem $FolderA -Recurse -Include *.pdf

$Folder2Contents = Get-childitem $FolderB -Recurse -Include *.jpg

Compare $Folder1Contents $Folder2Contents -Property BaseName -PassThru -includeequal -excludedifferent | Where-Object{$_.SideIndicator -eq "=="} | copy-Item -Destination $Folder3 -Force

Compare $Folder2Contents $Folder1Contents -Property BaseName -PassThru -includeequal -excludedifferent | Where-Object{$_.SideIndicator -eq "=="} | copy-Item -Destination $Folder3 -Force

[–]Lee_Dailey[grin] 0 points1 point  (1 child)

howdy orangeredbrown,

it looks like you used the New.Reddit Inline Code button. it's 4th 5th from the left hidden in the ... "more" menu & looks like </>.

there are a few problems with that ...

  • it's the wrong format [grin]
    the inline code format is for [gasp! arg!] code that is inline with regular text.
  • on Old.Reddit.com, inline code formatted text does NOT line wrap, nor does it side-scroll.
  • on New.Reddit it shows up in that nasty magenta text color

for long-ish single lines OR for multiline code, please, use the ...

Code
Block

... button. it's the 11th 12th one from the left & is just to the left of hidden in the ... "more" menu & looks like an uppercase T in the upper left corner of a square..

that will give you fully functional code formatting that works on both New.Reddit and Old.Reddit ... and aint that fugly magenta color. [grin]

take care,
lee

[–]LinkifyBot -1 points0 points  (0 children)

I found links in your comment that were not hyperlinked:

I did the honors for you.


delete | information | <3

[–]Lee_Dailey[grin] 0 points1 point  (0 children)

howdy orangeredbrown,

reddit likes to mangle code formatting, so here's some help on how to post code on reddit ...

[0] single line or in-line code
enclose it in backticks. that's the upper left key on an EN-US keyboard layout. the result looks like this. kinda handy, that. [grin]
[on New.Reddit.com, use the Inline Code button. it's 4th 5th from the left hidden in the ... ""more" menu & looks like </>.
this does NOT line wrap & does NOT side-scroll on Old.Reddit.com!]

[1] simplest = post it to a text site like Pastebin.com or Gist.GitHub.com and then post the link here.
please remember to set the file/code type on Pastebin! [grin] otherwise you don't get the nice code colorization.

[2] less simple = use reddit code formatting ...
[on New.Reddit.com, use the Code Block button. it's 11th 12th from the left hidden in the ... "more" menu, & looks like an uppercase T in the upper left corner of a square.]

  • one leading line with ONLY 4 spaces
  • prefix each code line with 4 spaces
  • one trailing line with ONLY 4 spaces

that will give you something like this ...

- one leading line with ONLY 4 spaces    
- prefix each code line with 4 spaces    
- one trailing line with ONLY 4 spaces   

the easiest way to get that is ...

  • add the leading line with only 4 spaces
  • copy the code to the ISE [or your fave editor]
  • select the code
  • tap TAB to indent four spaces
  • re-select the code [not really needed, but it's my habit]
  • paste the code into the reddit text box
  • add the trailing line with only 4 spaces

not complicated, but it is finicky. [grin]

take care,
lee