Powershell以递归方式获取目录

时间:2016-01-05 11:16:05

标签: windows powershell recursion

我试图以递归方式获取树中文件的列表,遗憾的是我无法弄明白。

下面的Powershell函数取自Michael Sorens对How to retrieve a recursive directory and file list from PowerShell excluding some files and folders?

的回答
function GetFiles($path = $pwd, [string[]]$exclude)
{
    foreach ($item in Get-ChildItem $path)
    {
        if ($exclude | Where {$item -like $_}) { continue }

        $item
        if (Test-Path $item.FullName -PathType Container)
        {
            GetFiles $item.FullName $exclude
        }
    }
} 

这是原始目录列表

  

C:\测试\作业\ AJenkinJob \构建\ 1   C:\测试\工作\ AJenkinJob \建立\ 1 \ build.xml文件   C:\测试\工作\ AJenkinJob \建立\ 1 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 1 \ junitResult.xml   C:\ test \ jobs \ AJenkinJob \ builds \ 1 \ log C:\ test \ jobs \ AJenkinJob \ builds \ 10   C:\测试\工作\ AJenkinJob \建立\ 10 \ build.xml文件   C:\测试\工作\ AJenkinJob \建立\ 10 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 10 \ junitResult.xml   C:\测试\工作\ AJenkinJob \建立\ 10 \日志   C:\测试\工作\ AJenkinJob \建立\ 11   C:\测试\工作\ AJenkinJob \建立\ 11 \ build.xml文件   C:\测试\工作\ AJenkinJob \建立\ 11 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 11 \ junitResult.xml   C:\测试\工作\ AJenkinJob \建立\ 11 \日志   C:\测试\工作\ AJenkinJob \建立\ 12   C:\测试\工作\ AJenkinJob \建立\ 12 \ build.xml文件   C:\测试\工作\ AJenkinJob \建立\ 12 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 12 \ junitResult.xml   C:\测试\工作\ AJenkinJob \建立\ 12 \日志   C:\测试\工作\ AJenkinJob \建立\ 13   C:\测试\工作\ AJenkinJob \建立\ 13 \ build.xml文件   C:\测试\工作\ AJenkinJob \建立\ 13 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 13 \ junitResult.xml   C:\测试\工作\ AJenkinJob \建立\ 27 \ build.xml文件   C:\测试\工作\ AJenkinJob \建立\ 27 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 27 \ junitResult.xml   C:\测试\工作\ AJenkinJob \建立\ 27 \日志   C:\测试\工作\ AJenkinJob \建立\ 28   C:\测试\工作\ AJenkinJob \建立\ 28 \ build.xml文件   C:\测试\工作\ AJenkinJob \建立\ 28 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 28 \ junitResult.xml   C:\测试\工作\ AJenkinJob \建立\ 28 \日志   C:\测试\作业\ AJenkinJob \构建\ 29

我运行函数传递:

GetFiles "." ["*1*"]

我希望得到(但不要)

  

C:\测试\作业\ AJenkinJob \构建\ 27 \的build.xml   C:\测试\工作\ AJenkinJob \建立\ 27 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 27 \ junitResult.xml   C:\测试\工作\ AJenkinJob \建立\ 27 \日志   C:\测试\工作\ AJenkinJob \建立\ 28   C:\测试\工作\ AJenkinJob \建立\ 28 \ build.xml文件   C:\测试\工作\ AJenkinJob \建立\ 28 \ changelog.xml   C:\测试\工作\ AJenkinJob \建立\ 28 \ junitResult.xml   C:\测试\工作\ AJenkinJob \建立\ 28 \日志   C:\测试\作业\ AJenkinJob \构建\ 29

我似乎无法弄清楚自己哪里出错:(

1 个答案:

答案 0 :(得分:3)

  

我运行函数传递:

GetFiles "." ["*1*"]

在参数模式下,PowerShell解析器会将命令的每个单独参数视为可扩展字符串,除非另有说明(见下文),这意味着PowerShell最终会将["*1*"]解释为字符串文字,函数内部的-like操作与您期望的操作非常不同。

只需放下方括号:

GetFiles . *1*

如果要显式传递数组作为参数,请使用数组子表达式运算符@()(这将导致解析器将参数计算为表达式,并在绑定之前将输出视为数组参数):

GetFiles . @("*1*")

如果您的数组需要包含多个值,请用逗号分隔:

GetFiles . @("*1*","*2*")

GetFiles . *1*,*2*

另一种方法是在内联Param()块中声明参数并使用ValueFromRemainingArguments参数属性,这样可以为命令提供无限数量的参数,就像{{1在C#中:

params

现在你可以做到:

function GetFiles
{
    param(
        [Parameter(Position=0)]
        $path = $pwd, 

        [Parameter(ValueFromRemainingArguments=$true)]
        [string[]]$exclude
    )

    foreach ($item in Get-ChildItem $path)
    {
        if ($exclude | Where {$item -like $_}) { continue }

        $item
        if (Test-Path $item.FullName -PathType Container)
        {
            GetFiles $item.FullName $exclude
        }
    }
}

你想要的一切