2

I have a curious problem. I have a function that takes a $srcDir and $destDir and $topDir $srcDir is in the format of \$topDir\subDir1\subDir2\subDir..n What I need is to append all subDir parts to the $destDir

My approach so far is to split-path until I reach $topDir and then append the resulting string to $destDir using join-path.

If no sub directories are appended to $destPath then the return is perfect.

If I append a path to $destPath then the return is $destPath $destPath

Here is the output in sample values

  • srcIn: C:\path\topdir\
  • destIn: \\server\path\
  • destOut: \\server\path\

Now if I have subdirectories

  • scrIn: C:\path\topdir\subpath\subpath1
  • destIn: \server\path\
  • destOut: \\server\path\subpath\subpath1 \\server\path\subpath\subpath1

Inside the function the path looks correct. There is no dbl of the destOut value. once I return from the function it has the double value.

How do I prevent this? I just wanted a simple function to obtain the sub directories and append to the destDir so I can preserve folder structure and move files to their appropriate directories.

Ty.

function GetSubDir
{
    param(
        [Parameter(Mandatory=$true)]
        [string]$filePath, 
        [Parameter(Mandatory=$true)]
        [string]$destDir,
        [string]$topDir="Disk1"
    )


    $tmpPath = Split-Path $filePath -parent
    $fileName = Split-Path $filePath -leaf 
    $tmp= Split-Path $filePath -leaf
    while ($tmp -ne $topDir)
    {

        if (test-path $tmpPath -PathType container)
        {
            if ($subDir){$subDir = "$tmp\$subDir"}
            else {$subDir = "$tmp\"}
        }
        else {$subDir = "$tmp"}
        $tmp = Split-Path $tmpPath -leaf
        $tmpPath = Split-Path $tmpPath -parent

    }

    $destPath = Join-Path $destDir $subDir
    if (!(Test-Path $destPath)) {md $destPath}
    if (Test-Path $destPath -PathType container) 

    #name is set in calling function
    {$destPath = Join-Path $destPath $name}

    return $destPath
}
1
  • Seems like an awful lot of code to do ($srcPath -replace ".*\\$topDir", "$destDir\\$topDir")... Commented Mar 23, 2014 at 2:58

2 Answers 2

7

The md function (alias for new-item) returns the directory it creates. Since you don't do anything with that value, it is added to the output stream of the function.

To fix this, do one of these:

md $destPath | out-null

[null]md $destPath
Sign up to request clarification or add additional context in comments.

2 Comments

While this is technically the reason for the return value, I do like the answer below as it accomplishes the same thing in a better format. Thank you everyone who helped remind me that functions often return more than you think they do. I had forgotten that. I was expecting it to only return the variable value I specified to the right of the expression return $destDir.
Damn, after hours of hacking around, this finally saved my life, thanks!
1

With a tip of the hat to @TessellatingHecker, let me agree that one line will suffice, but I believe it is this one line that is needed:

$srcPath -replace [Regex]::Escape($topDir), $destDir

Now let's encapsulate that in a function...

function MapSubDir($srcPath, $topDir, $destDir)
{
    $srcPath -replace [Regex]::Escape($topDir), $destDir
}

And feed it your original two test cases to observe you get your desired results:

PS> $srcPath= "C:\path\topdir\"
PS> $topDir= "C:\path\topdir\"
PS> $destDir= "\\server\path\"
PS> MapSubDir $srcPath $topDir $destDir
\\server\path

PS> $srcPath = "C:\path\topdir\subpath\subpath1"
PS> MapSubDir $srcPath $topDir $destDir
\\server\path\subpath\subpath1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.