通过字符串变量传递Powershell Get-ChildItem过滤器参数不起作用

时间:2019-06-16 18:27:37

标签: powershell powershell-2.0 get-childitem

在我的脚本中,我具有下面的函数,该函数返回字符串“ * .csproj”,“ *。vbproj”,“ *。sln”。假设我总是将诸如“ csproj,vbproj,sln”之类的字符串传递给$ filter参数:

Function Create-Filter($filter)
{    
    $str = $filter.Split(',') | ForEach-Object {"""*.$($_.Trim())"""}

    $str = $str -join ', '
    [string]$str
    return
}

稍后我会执行脚本:

$filter = Create-Filter($filter)
$myFiles = Get-ChildItem $source -Include $filter -Recurse  

但是$ myFiles为空,Get-ChildItem不返回任何内容。我知道问题出在传递给Get-ChildItem的$ filter参数中,但我不知道如何解决。

无论如何,如果从Powershell控制台执行以下操作,那么它会起作用:

PS > $filter = "*.csproj", "*.vbproj", "*.sln"
PS > Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $filter -Recurse

那我在做什么错了?

我的powershell版本如下图所示:

enter image description here

更新(解决方案): AdminOfThings提出的解决方案有效。 就我而言,应用AdminOfThings无法正常工作,因为我在代码中犯了一个错误。我正在将Create-Filter函数返回的值分配给与作为参数传递的变量相同的变量,如下所示:

$filter = Create-Filter ($filter)
Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $filter -Recurse

为了使其正常工作,我在下面做了以下操作:

$formattedfilter = Create-Filter ($filter)
Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $formattedfilter -Recurse

...也就是说,使用其他变量按函数分配返回值,而不是使用与我作为参数传递的值相同的方法。

2 个答案:

答案 0 :(得分:2)

简而言之,您需要从函数中删除文字双引号(用单双引号替换三重双引号),-Join和字符串转换([string])。基本上,所有使输出字符串化的内容都需要删除。

Function Create-Filter($filter)
{    
    $filter.Split(',') | ForEach-Object {"*.$($_.Trim())"}
    return
}

-Include参数接受单个字符串或字符串数​​组。传递-Include "string1","string2"时,就是将字符串数组传递给命令。在您的过滤器中,您正在创建一个包含文字引号和逗号的字符串。此处的细微之处是在引号中包括逗号,从而创建了一个包含引号的字符串,而引号 BETWEEN 逗号创建了一个逗号分隔的字符串列表。如此有效,该命令正在读取-Include '"string1","string2"',它将什么也找不到。即使您的函数输出的文本看起来与您直接在命令中键入的文本相同,PowerShell也会以不同的方式解释这些值。

您可以在下面看到的行为,其中PowerShell会将函数的输出解释为单个字符串。

create-filter ("txt","csv")
"*.txt", "*.csv"
(create-filter ("txt","csv")).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

下面的数组语法(用逗号分隔的字符串类型列表)输出不同的结果。

"*.txt","*.csv"
*.txt
*.csv
("*.txt","*.csv").gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

执行代码:

$str = "txt,csv"
create-filter $str
*.txt
*.csv
$filter = create-filter $str
Get-ChildItem . -Include $filter -Recurse
    Directory: C:\temp\test1


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         6/8/2019  10:47 AM             68 -44.csv
-a----         6/8/2019  10:47 AM            101 -54.csv
-a----        6/11/2019   8:50 AM            229 count.txt
-a----        6/11/2019   8:58 AM            170 destination.txt
-a----        6/11/2019   8:53 AM            302 f.txt
-a----        6/12/2019   6:36 AM            294 hashash.txt
-a----         6/6/2019   1:14 PM              4 jaf.csv
-a----         6/6/2019   1:31 PM              0 job1.txt

答案 1 :(得分:0)

嗯,我会用-filter更快。

ls -r D:\Path\To\My\Root\Folder -filter *.csproj,*.vbproj,*.sln

编辑:噢,那不行。但是,确实如此。我不确定您需要什么功能。

ls -r D:\Path\To\My\Root\Folder -include *.csproj,*.vbproj,*.sln

$source = 'D:\Path\To\My\Root\Folder'
$filter = '*.csproj','*.vbproj.*','*.sln' # or
$filter = echo *.csproj,*.vbproj,*.sln 

ls -r $source -include $filter