Cách lọc đúng nhiều chuỗi trong tập lệnh sao chép PowerShell


80

Tôi đang sử dụng tập lệnh PowerShell từ câu trả lời này để sao chép tệp. Sự cố phát sinh khi tôi muốn bao gồm nhiều loại tệp bằng cách sử dụng bộ lọc.

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

hoạt động như một giấc mơ. Tuy nhiên, vấn đề phát sinh khi tôi muốn bao gồm nhiều loại tệp bằng cách sử dụng bộ lọc.

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 }

Cung cấp cho tôi lỗi sau:

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

Tôi có lặp khác nhau của dấu ngoặc đơn, không có dấu ngoặc đơn, -filter, -includeđịnh vùi như biến (ví dụ $fileFilter) và mỗi lần nhận được lỗi trên, và luôn luôn trỏ đến bất cứ điều gì sau -filter.

Ngoại lệ thú vị đó là khi tôi viết mã -filter "*.gif,*.jpg,*.xls*,*.doc*,*.pdf*,*.wav*,*.ppt*". Không có lỗi, nhưng tôi và không nhận được kết quả và không có gì trở lại bảng điều khiển. Tôi nghi ngờ tôi đã vô tình mã hóa một andđiều không đúng với tuyên bố đó?

Vậy tôi đang làm gì sai, và làm thế nào để tôi có thể sửa nó?

Câu trả lời:


194

-Filter chỉ chấp nhận một chuỗi duy nhất. -Include chấp nhận nhiều giá trị, nhưng đủ điều kiện đối số -Path . Mẹo là thêm \*vào cuối đường dẫn, sau đó sử dụng -Có bao gồm để chọn nhiều phần mở rộng. BTW, trích dẫn chuỗi là không cần thiết trong các đối số cmdlet trừ khi chúng chứa khoảng trắng hoặc ký tự đặc biệt bao.

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

Lưu ý rằng điều này sẽ hoạt động bất kể $ originalPath kết thúc bằng dấu gạch chéo ngược hay không, vì nhiều dấu gạch chéo ngược liên tiếp được hiểu là một dấu phân cách đường dẫn duy nhất. Ví dụ, hãy thử:

Get-ChildItem C:\\\\\Windows

5
WooHoo! \*Thủ thuật đó vừa giải quyết được khoảng sáu vấn đề. Thật sự cảm ơn!
dwwilson66

17
Lưu ý rằng ký tự đại diện ( \*) không cần thiết khi -Recurseđược chỉ định.
Ohad Schneider

vì lý do nào đó điều này không hoạt động khi tìm kiếm thư mục?
Ross Presser

Thêm -recurse phép này để tiếp cận với các thư mục phụ
Derek Evermore

2

Một cái gì đó như thế này sẽ hoạt động (nó đã làm cho tôi). Lý do muốn sử dụng -Filterthay vì -Includebao gồm có hiệu suất rất lớn so với -Filter.

Dưới đây chỉ lặp lại từng loại tệp và nhiều máy chủ / máy trạm được chỉ định trong các tệp riêng biệt.

##  
##  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

điều này rất đúng và trong 5 câu hỏi tương tự ở đây, không ai chỉ ra rằng mặc dù chúng ta không thể làm -filter *.jpg, *.pngđược, nhưng làm -filter * .jpg trong một lần vẫn nhanh hơn do -filter * .png và nối kết quả, hơn làm một -Include *.jpg, *.png". Tôi có một thư mục chứa 126k tệp và 18k thư mục. Tôi đang tìm kiếm một tệp và một thư mục trong mỗi thư mục một cách đệ quy. sử dụng -Filter mất 5 giây và sử dụng -Bao gồm 30 giây. Làm -Filter hai lần trong 10 giây nhanh hơn ba lần so với một -Filter.
papo

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

Chào mừng bạn đến với Stack Overflow! Câu trả lời này xuất hiện trong hàng đợi đánh giá chất lượng thấp, có thể là do bạn không giải thích nội dung. Nếu bạn giải thích điều này (trong câu trả lời của mình), bạn có nhiều khả năng nhận được nhiều phiếu tán thành hơn — và người hỏi thực sự học được điều gì đó!
The Guy with The Hat

2
Ngoài ra, nó lặp lại mã từ câu trả lời tôi đã đăng trước đó, ngoại trừ việc nó bao gồm danh sách các phần mở rộng trong toán tử đánh giá biểu thức mảng ( @()), điều này không cần thiết, vì danh sách được phân tách bằng dấu phẩy vốn được đánh giá là một mảng.
Adi Inbar

-2

1
Điều đó đã không hoạt động. :( -filter -include *.file, *.types -filter -include (*.file, *.types), -filter -include "*.file", "*.types"-filter -include ("*.file", "*.types")tất cả đều bị lỗi theo câu hỏi của tôi ở trên. Việc loại bỏ -filtertham số và chỉ bao gồm -include(các lần lặp lại dấu ngoặc kép và parens giống nhau) không dẫn đến lỗi thời gian chạy , nhưng không có kết quả nào được đặt trong thư mục đích.
dwwilson66
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.