Windows: Sao chép tập tin / di chuyển với tên tệp biểu thức chính quy?


10

tôi về cơ bản muốn chạy:

C:\>xcopy [0-9]{13}\.(gif|jpg|png) s:\TargetFolder /s

tôi biết xcopy không hỗ trợ tìm kiếm tên tệp biểu thức chính quy.

tôi không thể tìm ra làm thế nào để tìm ra nếu PowerShell có một Cmdlet sao chép tập tin; và nếu có, làm thế nào để tìm hiểu xem nó có hỗ trợ khớp tên tệp biểu thức chính quy không.

Bất cứ ai cũng có thể nghĩ ra một cách để thực hiện sao chép / di chuyển tệp đệ quy với khớp tên tệp regex?


1
cái này nên được chuyển sang stackoverflow phải không?
user33788

1
@smoknheap: Có thể là cả hai, tôi thấy rằng kịch bản Powershell đang ngày càng trở thành công cụ Power User. Đây là nhiều hơn một câu hỏi thay thế xcopy sau đó là một câu hỏi kịch bản.
Doltknuckle

Câu trả lời:


4

Tôi thích sử dụng tất cả các lệnh Powershell khi tôi có thể. Sau một chút thử nghiệm, đây là điều tốt nhất tôi có thể làm.

$source = "C:\test" 
$destination = "C:\test2" 
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"

$bin = Get-ChildItem -Path $source | Where-Object {$_.Name -match $filter} 
foreach ($item in $bin) {Copy-Item -Path $item.FullName -Destination $destination}

Ba dòng đầu tiên chỉ để làm cho nó dễ đọc hơn, bạn có thể xác định các biến bên trong các lệnh thực tế nếu bạn muốn. Chìa khóa của mẫu mã này là lệnh "Where-Object" là bộ lọc chấp nhận khớp biểu thức chính quy. Cần lưu ý rằng hỗ trợ biểu thức thường xuyên là một chút lạ. Tôi tìm thấy một thẻ tham khảo PDF đây có các ký tự được hỗ trợ ở phía bên trái.

[CHỈNH SỬA]

Như "@Johannes Rössel" đã đề cập, bạn cũng có thể giảm hai dòng cuối xuống một dòng.

((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination

Sự khác biệt chính là cách của Julian thực hiện lọc đối tượng và cách của tôi là lọc văn bản. Khi làm việc với Powershell, hầu như luôn luôn tốt hơn khi sử dụng các đối tượng.

[EDIT2]

Như @smoknheap đã đề cập, các tập lệnh trên sẽ làm phẳng cấu trúc thư mục và đặt tất cả các tệp của bạn vào một thư mục. Tôi không chắc chắn nếu có một công tắc giữ lại cấu trúc thư mục. Tôi đã thử công tắc -Recurse và nó không giúp được gì. Cách duy nhất tôi có được điều này để làm việc là quay trở lại thao tác chuỗi và thêm các thư mục vào bộ lọc của tôi.

$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
    Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    }

Tôi chắc chắn rằng có một cách thanh lịch hơn để làm điều này, nhưng từ các thử nghiệm của tôi, nó hoạt động. Nó thu thập mọi thứ và sau đó lọc cho cả đối tượng tên và đối tượng thư mục. Tôi đã phải sử dụng phương thức ToString () để có quyền truy cập vào thao tác chuỗi.

[EDIT3]

Bây giờ nếu bạn muốn báo cáo đường dẫn để đảm bảo bạn có mọi thứ chính xác. Bạn có thể sử dụng lệnh "Write-Host". Đây là mã sẽ cung cấp cho bạn một số gợi ý về những gì đang xảy ra.

cls
$source = "C:\test" 
$destination = "C:\test2" 
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"

$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
    Write-Host "
----
Obj: $item
Path: "$item.fullname"
Destination: "$item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    }

Điều này sẽ trả về các chuỗi có liên quan. Nếu bạn không nhận được gì ở đâu đó, bạn sẽ biết mặt hàng nào đang gặp vấn đề.

Hi vọng điêu nay co ich


Lưu ý rằng bạn không cần sử dụng $item.FullName ở đó - thuộc tính thích hợp được lấy tự động nếu bạn truyền đối tượng FileInfo (imho, bạn không nên, vì sức mạnh của PowerShell đến từ việc truyền các đối tượng có cấu trúc, không phải chuỗi). Hơn nữa, bạn có thể đặt mọi thứ vào một đường ống dẫn duy nhất: ((gci $source) -match $filter) | cp -dest $destination (hơi thích nghi với sự ngắn gọn - hãy thoải mái thay đổi; tôi chỉ nói rằng foreach là không cần thiết ở đó).
Joey

Khi tôi đang thử nghiệm nó, tôi không thể đưa các vật thể vào ống chính xác. Đó là lần lượt buộc tôi phải sử dụng lệnh foreach. Tôi sẽ thử mã của bạn và xem điều gì sẽ xảy ra. Cảm ơn đã chỉ ra rằng.
Doltknuckle

cái này có vấn đề giống như của tôi không, nơi nó làm phẳng thư mục đích? xcopy thường sẽ bảo vệ cấu trúc thư mục trên thư mục đích, phải không?
user33788

Copy-Item : Cannot bind argument to parameter 'Path' because it is null
Ian Boyd

Xin lưu ý rằng Trim không có ý định xóa một chuỗi từ cuối chuỗi khác, thay vào đó, nó sẽ xóa tất cả các trường hợp của các ký tự trong chuỗi tham số khỏi đầu và cuối của chuỗi được gọi. Trong trường hợp của bạn nếu $item.Name chứa một chữ hoa C nó cũng sẽ loại bỏ ký tự ổ đĩa C từ đầu chuỗi.
Andris

2

PowerShell là một công cụ tuyệt vời cho nhiệm vụ đó. Bạn có thể dùng Sao chép-Mục cmdlet cho quá trình sao chép. Bạn có thể dẫn nó với các lệnh ghép ngắn khác cho các lệnh sao chép phức tạp, đây là ai đó đã làm chính xác điều đó :)

Các biểu thức chính quy sử dụng lớp .NET RegEx từ không gian tên System.Text.RegularExpressions, có cách nhanh chóng trên các lớp này

PowerShell cũng có toán tử -match và -replace có thể được sử dụng khi đường ống với mục sao chép

Ngoài ra còn có các công cụ giúp bạn tạo chính RegEx, ví dụ: Bạn thân


Tôi -match-replace nên được đề cập trước khi đi vào System.Text.RegularExpressions.RegEx. Ít nhất là đối với tôi, tôi hiếm khi sử dụng [regex] trực tiếp; Tuy nhiên, tôi làm thường xuyên sử dụng -match-replace khai thác. Đối với việc tạo các biểu thức thông thường, tôi thấy PowerShell khá hữu ích trong việc kiểm tra và tinh chỉnh một biểu thức chính mà bạn đang viết.
Joey

Tôi đã yêu cầu câu trả lời cho câu trả lời của bạn trong câu hỏi này: superuser.com/questions/149808/
Ian Boyd

0

như một ý tưởng nhưng cần một số công việc

thư mục -r | ? {$ _ -match '[0-9] {13} \. (gif | jpg | png)'} | % {xcopy $ _. tên đầy đủ c: \ temp}

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.