递归逻辑

时间:2016-08-09 01:32:34

标签: recursion powershell-v2.0 cab

我一直在研究一种PowerShell脚本,该脚本在出租嵌套文件夹时会保留目录结构。但是,我在使递归逻辑正确方面遇到了一些困难。

这是一个粗略的,所以还没有任何try / catch错误代码。我已经注释了Remove-Item以防止意外运行。

我为此制定的逻辑如下。

  • 检查&获取子目录的基础树
  • 进入一个级别并再次检查
  • 继续,直到没有目录,然后返回一级。
  • Cab目录,删除目录,写入自动提取日志(子目录cab的文件名)。
  • 重复上一级进程并继续直到基目录
function Chkfordir ($clevel)
{
    $dir = dir $clevel | ? { $_.PSIsContainer -eq $true } #Does Current Level have Folders?
    if($dir -ne $null)    # Yes
    {
        Chkfordir $dir        #Go Deeper
    }
    if ($dir -eq $null)   #Deepest Branch
    {
        return                # Go Back One Level and begin Cabbing
    }

    $dir | % { 
        Compress-Directory $_.FullName (".\" + [string]$_.Name + ".cab")
        echo ($_.FullName + ".cab" >> .\cleaf.log"
        #Remove-Item -Recurse $_.FullName
        return
    } 
}

函数调用Compress-Directory来自here

修改内容:

将很快重新发布代码(08/18)

编辑08/18所以我终于有机会测试它,逻辑似乎现在正常工作。有一些问题。

大多数困难都来自于PowerShell陷阱以及Compress-Directory与路径无关的未被注意的问题。看起来我以后需要重新编写这个函数才能与路径无关。

powershell gotcha正在对管道上的值进行类型更改。显然,从函数目录返回后,项目从System.IO.FileInfo更改为System.IO.DirectoryInfo,具有不同名称的成员函数。

Echo被Add-Content取代,因为重定向操作符不在powershell中工作。

还有一些无法解释的州也要与之抗衡。没有文件的叶子目录会导致Compress-Directory出错或者无文件创建完成(因此不保留层次结构)。

解决方法是在返回之前为叶子文件夹添加Add-Content,并将Add-Content移动到Compress-Directory之前,这样每个目录中至少有一个文件。

我已将我当前的版本包括在内,但这是一项正在进行中的工作。

function Chkfordir ($clevel)
{
    $dir = dir $clevel | ? { $_.PSIsContainer -eq $true } # Get Folders?
    if ($dir -eq $null) {  #Check if deepest branch
        Add-Content (Join-Path $_.PSPath "\leaf.log") ([string]$_.FullName + ".cab")
        return $_                # Return one level up and cab
    }

    $dir | % { #for each sub go deeper
        Chkfordir $_.FullName
        Add-Content (Join-Path $_.PSParentPath "\branch.log") ([string]$_.FullName + ".cab")
        Compress-Directory $_.FullName ([string]$_.Name + ".cab")
        #Remove-Item $_.FullName -recurse
    }          
}

1 个答案:

答案 0 :(得分:0)

您需要递归每个子目录并在递归调用返回后压缩它:

function Chkfordir($clevel) {
    Get-ChildItem $clevel |
        Where-Object { $_.PSIsContainer } |
        ForEach-Object {
            Chkfordir $_
            Compress-Directory ...
            ...
        }
}

这样你首先自动下降,然后在你返回时创建档案。