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はそのステートメントで不注意に暗黙のコードを書いたのではないかと思いますか?

それで、私は何が間違っているのですか、そしてどうすればそれを修正できますか?

回答:


194

-フィルターは単一の文字列のみを受け入れます。-Includeは複数の値を受け入れますが、-Path引数を修飾します。秘訣は\*、パスの最後に追加してから、-Includeを使用して複数の拡張子を選択することです。ところで、スペースやシェルの特殊文字が含まれていない限り、コマンドレット引数で文字列を引用する必要はありません。

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

複数の連続するバックスラッシュは単一のパス区切り文字として解釈されるため、これは$ originalPathがバックスラッシュで終了するかどうかに関係なく機能することに注意してください。たとえば、次のことを試してください。

Get-ChildItem C:\\\\\Windows

5
WooHoo!その\*トリックはちょうど約6つの問題を解決しました。素晴らしいです、ありがとう!
dwwilson66 2013

17
が指定されている\*場合、ワイルドカード()は不要であることに注意してください-Recurse
オハドシュナイダー2015

何らかの理由で、ディレクトリを検索するときにこれが機能しませんか?
ロスプレッサー2015

-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 * .pngを実行して結果を結合するよりも、-filter * .jpgを一度に実行する方が速い可能性があることを誰も指摘していません。1つ実行し-Include *.jpg, *.png"ます。126kのファイルと18kのフォルダーを含むフォルダーがあります。各フォルダで1つのファイルと1つのフォルダを再帰的に検索しています。-Filterの使用には5秒かかり、-Includeの使用には30秒かかります。-Filterを10秒間に2回実行すると、1回の実行よりも3倍高速になります。
papo

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

Stack Overflowへようこそ!この回答は、おそらく内容を説明しなかったために、低品質のレビューキューに表示されました。これを(あなたの答えで)説明すると、より多くの賛成票を獲得する可能性がはるかに高くなり、質問者は実際に何かを学びます!
帽子をかぶった男

2
また、@()コンマ区切りのリストは本質的に配列として評価されるため、拡張機能のリストを配列式の評価演算子()で囲むことを除いて、以前に投稿した回答のコードを繰り返します。
Adi Inbar 2014

-2

インクルードを使用するのが最も簡単な方法です

http://www.vistax64.com/powershell/168315-get-childitem-filter-files-multiple-extensions.html


1
それはうまくいきませんでした。:( -filter -include *.file, *.types -filter -include (*.file, *.types)-filter -include "*.file", "*.types"および-filter -include ("*.file", "*.types")上記のすべての私の質問ごとのようにしてエラーが発生した排除。-filterパラメータだけを含む-include(引用符と括弧の同じ反復が)には至らなかったランタイムエラーが、コピー先のディレクトリには、結果セットがありませんでした。
dwwilson66
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.