如何在PowerShell复制脚本中正确过滤多个字符串


80

我正在使用此答案中的PowerShell脚本进行文件复制。当我想使用过滤器包括多种文件类型时,就会出现问题。

Get-ChildItem $originalPath -filter "*.htm"  | `
   foreach{ $targetFile = $htmPath + $_.FullName.SubString($originalPath.Length); ` 
 New-Item -ItemType File -Path $targetFile -Force;  `
 Copy-Item $_.FullName -destination $targetFile }

像梦一样工作。但是,当我想使用过滤器包含多种文件类型时,就会出现问题。

Get-ChildItem $originalPath ` 
  -filter "*.gif","*.jpg","*.xls*","*.doc*","*.pdf*","*.wav*",".ppt*")  | `
   foreach{ $targetFile = $htmPath + $_.FullName.SubString($originalPath.Length); ` 
 New-Item -ItemType File -Path $targetFile -Force;  `
 Copy-Item $_.FullName -destination $targetFile }

给我以下错误:

Get-ChildItem : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Filter'. Specified method is not supported.
At F:\data\foo\CGM.ps1:121 char:36
+ Get-ChildItem $originalPath -filter <<<<  "*.gif","*.jpg","*.xls*","*.doc*","*.pdf*","*.wav*",".ppt*" | `
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.GetChildItemCommand

我有括号的各种迭代,没有括号,-filter-include,定义夹杂物变量(例如,$fileFilter每次时间),并出现上述错误,始终指向后面的任何内容-filter

有趣的例外是当我编码时-filter "*.gif,*.jpg,*.xls*,*.doc*,*.pdf*,*.wav*,*.ppt*"。没有错误,但是我并没有得到任何结果,也没有返回控制台。我怀疑我在不经意间编码了and该陈述的隐含含义?

那么我在做什么错了,我该如何纠正呢?

Answers:


193

-Filter仅接受单个字符串。-Include接受多个值,但限定-Path参数。技巧是将附加\*到路径的末尾,然后使用-Include选择多个扩展名。顺便说一句,除非cmdlet参数中包含空格或shell特殊字符,否则在字符串中不需要用引号引起来。

Get-ChildItem $originalPath\* -Include *.gif, *.jpg, *.xls*, *.doc*, *.pdf*, *.wav*, .ppt*

请注意,无论$ originalPath是否以反斜杠结尾,这都将起作用,因为多个连续的反斜杠将被解释为单个路径分隔符。例如,尝试:

Get-ChildItem C:\\\\\Windows

5
呜呜!这个\*技巧解决了大约六个问题。太好了,谢谢!
dwwilson66 2013年

17
请注意,\*如果-Recurse指定,则不需要通配符()。
Ohad Schneider

由于某种原因,这在搜索目录时不起作用?
Ross Presser

添加-Recurse可以将其扩展到子文件夹
Derek Evermore

2

这样的事情应该起作用(对我有用)。想要使用-Filter而不是的原因-Include是,与相比,include会对性能造成巨大影响-Filter

下面只是循环每种文件类型以及在单独文件中指定的多个服务器/工作站。

##  
##  This script will pull from a list of workstations in a text file and search for the specified string


## Change the file path below to where your list of target workstations reside
## Change the file path below to where your list of filetypes reside

$filetypes = gc 'pathToListOffiletypes.txt'
$servers = gc 'pathToListOfWorkstations.txt'

##Set the scope of the variable so it has visibility
set-variable -Name searchString -Scope 0
$searchString = 'whatYouAreSearchingFor'

foreach ($server in $servers)
    {

    foreach ($filetype in $filetypes)
    {

    ## below creates the search path.  This could be further improved to exclude the windows directory
    $serverString = "\\"+$server+"\c$\Program Files"


    ## Display the server being queried
    write-host “Server:” $server "searching for " $filetype in $serverString

    Get-ChildItem -Path $serverString -Recurse -Filter $filetype |
    #-Include "*.xml","*.ps1","*.cnf","*.odf","*.conf","*.bat","*.cfg","*.ini","*.config","*.info","*.nfo","*.txt" |
    Select-String -pattern $searchstring | group path | select name | out-file f:\DataCentre\String_Results.txt

    $os = gwmi win32_operatingsystem -computer $server
    $sp = $os | % {$_.servicepackmajorversion}
    $a = $os | % {$_.caption}

    ##  Below will list again the server name as well as its OS and SP
    ##  Because the script may not be monitored, this helps confirm the machine has been successfully scanned
        write-host $server “has completed its " $filetype "scan:” “|” “OS:” $a “SP:” “|” $sp


    }

}
#end script

这是真的,在这里有5个类似的问题,没有人指出,尽管我们做不到,但一次-filter *.jpg, *.png执行-filter * .jpg的速度可能比-filter * .png并加入结果的速度要快做一个-Include *.jpg, *.png"。我有一个包含126k文件和18k文件夹的文件夹。我递归地在每个文件夹中搜索一个文件和一个文件夹。使用-Filter需要5秒,使用-Include需要30秒。在10秒内执行-Filter两次比执行-include go快三倍。
papo

0
Get-ChildItem $originalPath\* -Include @("*.gif", "*.jpg", "*.xls*", "*.doc*", "*.pdf*", "*.wav*", "*.ppt")

欢迎使用Stack Overflow!这个答案出现在低质量的审核队列中,大概是因为您没有解释内容。如果您确实解释了这一点(在您的答案中),您更有可能获得更多的赞成票-提问者实际上学到了一些东西!
戴帽子的家伙

2
另外,它重复了我之前发布的答案中的代码,只是它用一个数组表达式求值运算符(@())来封装扩展列表,这是多余的,因为逗号分隔的列表本质上是作为数组求值的。
Adi Inbar 2014年

-2

1
那没用。:( -filter -include *.file, *.types -filter -include (*.file, *.types)-filter -include "*.file", "*.types"-filter -include ("*.file", "*.types")所有出错了按我上面的问题消除了,-filter参数,只是包括-include没有造成(引号和括号的相同的迭代)运行时错误,但有在目标目录中没有结果集。
dwwilson66
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.