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 를 사용 하여 여러 확장을 선택하는 것입니다. BTW, 공백이나 셸 특수 문자를 포함하지 않는 한 cmdlet 인수에는 인용 문자열이 필요하지 않습니다.

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

여러 연속 백 슬래시는 단일 경로 구분자로 해석되기 때문에 $ originalPath 가 백 슬래시로 끝나는 지 여부에 관계없이 작동합니다 . 예를 들어, 다음을 시도하십시오.

Get-ChildItem C:\\\\\Windows

5
우후! 그 \*트릭으로 약 6 개의 문제가 해결되었습니다. 굉장하고 감사합니다!
dwwilson66 2013 년

17
가 지정 \*되면 와일드 카드 ( )가 필요하지 않습니다 -Recurse.
Ohad Schneider 2015 년

어떤 이유로 디렉토리를 검색 할 때 작동하지 않습니까?
Ross Presser 2015 년

추가 -Recurse이 하위 폴더에 밖으로 도달 할 수
데릭 에버 모어에게

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를 수행하는 것이 더 빠를 수 있다고 지적하지 않았습니다. 하나를하십시오 -Include *.jpg, *.png". 126k 파일과 18k 폴더가 포함 된 폴더가 있습니다. 재귀 적으로 각 폴더에서 하나의 파일과 하나의 폴더를 검색하고 있습니다. -Filter를 사용하면 5 초가 걸리고 -Include 30secs를 사용합니다. -Filter를 10 초에 두 번 수행하는 것은 하나의 -Include go보다 세 배 빠릅니다.
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.