2011-04-07 51 views
13

Tôi đang học Regex nhưng tôi không biết cách đổi tên các tệp sau đây thành những tệp tôi muốn. Bạn có thể giúp tôi được không.Sử dụng Regex/Powershell để đổi tên các tệp

BTW, tôi thấy nó thực sự hữu ích khi sử dụng Powershell để đổi tên tệp và có thể chấp nhận Regex.

filename__Accelerated_C ____ Practical_Programming_by_Example.chm ->C Lập trình thực tế bởi Example.chm

filename__Python_Essential_Reference__2nd_Edition_.pdf ->Python Essential Reference 2nd Edition.pdf

filename__Text_Processing_in_Python .chm ->Xử Lý Văn Bản trong Python.chm

Tôi cũng bao gồm một số công cụ Regex trực tuyến miễn phí mà tôi thích sử dụng nhất, có thể có ích cho người khác.

http://gskinner.com/RegExr/

http://www.rubular.com/

và cheatsheet

http://krijnhoetmer.nl/stuff/regex/cheat-sheet/

+0

Tôi là chuyên gia về regex, tôi ăn tác giả liên kết của bạn cho bữa sáng! – sln

+0

Đầu tiên phải là ** Lập trình thực hành C++ được tăng tốc bằng Ví dụ ** imho. – YOU

Trả lời

13

này nên làm việc:

ls | %{ ren $_ $(($_.name -replace '^filename_+','') -replace '_+',' ') } 
+1

Tại sao sử dụng '$' trong tham số thứ hai. Tôi thấy điều này cũng hoạt động: 'ls | % {ren $ _ (($ _ -replace 'filename_ +', '') -replace '_ +', '')} ' –

+1

quên nhận xét của tôi, $ là cần thiết để cắt bỏ không gian cuối cùng trước đuôi tệp :) . Regex của bạn hoạt động hoàn hảo! –

+0

Trong trường hợp bất kỳ ai khác có cùng một vấn đề: Nếu vì bất kỳ lý do gì, việc sử dụng khối foreach sẽ dẫn đến lỗi "không thể đổi tên vì mục không tồn tại", hãy thử sử dụng khối tập lệnh làm đối số cho -NewName, như được hiển thị trong câu trả lời của người dùng @stej (làm việc cho tôi).Tôi không thể hiểu tại sao điều này nên tạo nên sự khác biệt. Có lẽ ai đó có ý tưởng? – gimpf

0

Hãy thử điều này:

$filename = $filename -creplace '_+\.', '.' 
$filename = $filename -creplace '_+', ' ' 
23

Hãy thử điều này một:

Get-ChildItem directory | Rename-Item -NewName { $_.Name -replace '^filename_+','' -replace '_+',' ' } 

Lưu ý rằng tôi chỉ ống các đối tượng để Rename-Item, nó không phải là thực sự cần thiết để làm điều đó thông qua Foreach-Object (bí danh là %).

Cập nhật

tôi không có bất cứ điều gì ghi chép về 'ma thuật' với scriptblocks. Nếu tôi nhớ chính xác, nó có thể được sử dụng nếu thuộc tính là ValueFromPipelineByPropertyName=$true:

function x{ 
    param(
     [Parameter(ValueFromPipeline=$true)]$o, 
     [Parameter(ValueFromPipelineByPropertyName=$true)][string]$prefix) 
    process { 
     write-host $prefix $o 
    } 
} 
gci d:\ | select -fir 10 | x -prefix { $_.LastWriteTime } 
+1

Woohoo. 1 để loại bỏ giai đoạn đường ống 'Foreach' không cần thiết. :-) –

+0

hey cool. Các tài liệu không nói rằng bạn có thể sử dụng một scriptblock như một param ở đó. Đây có phải là một tính năng của nhiều lệnh ghép ngắn khác không? – zdan

+0

@zdan, tôi không biết tài liệu được ghi ở đâu. Có thể tìm thấy nó trên một blog. Không ai trả lời cho đến nay (câu hỏi trên Twitter). Xem câu trả lời đã chỉnh sửa của tôi. – stej

Các vấn đề liên quan