2010-09-29 36 views
16

Tôi đang cố gắng đổi tên một loạt tệp đệ quy bằng Powershell 2.0. Cấu trúc thư mục trông như thế này:Đổi tên tệp thành chữ thường trong Powershell

Leaflets 
+ HTML 
    - File1 
    - File2 
    ... 
+ HTMLICONS 
    + IMAGES 
    - Image1 
    - Image2 
    - File1 
    - File2 
    ... 
+ RTF 
    - File1 
    - File2 
    ... 
+ SGML 
    - File1 
    - File2 
    ... 

Tôi đang sử dụng lệnh sau:

get-childitem Leaflets -recurse | rename -newname { $_.name.ToLower() } 

và có vẻ như để đổi tên các tập tin, nhưng phàn nàn về các thư mục con:

Rename-Item : Source and destination path must be different. 

tôi tải lại dữ liệu hàng tháng bằng cách sử dụng robocopy, nhưng các thư mục không thay đổi, vì vậy tôi có thể đổi tên chúng bằng tay. Có cách nào để nhận được get-children để bỏ qua các thư mục con (như find Leaflets -type f ...) không?

Cảm ơn.

CẬP NHẬT: Có vẻ như sự cố xảy ra với các tệp đã là tất cả các trường hợp thấp hơn. Tôi đã cố gắng thay đổi lệnh để:

get-childitem Leaflets -recurse | if ($_.name -ne $_name.ToLower()) rename -newname { $_.name.ToLower() } 

nhưng bây giờ Powershell phàn nàn rằng if không phải là một lệnh, chức năng, vv Tôi ống Can đầu ra của get-childitem đến một tuyên bố if?

UPDATE 2: Đây hoạt động:

$files=get-childitem Leaflets -recurse 
foreach ($file in $files) 
{ 
    if ($file.name -ne $file.name.ToLower()) 
    { 
     rename -newname { $_.name.ToLower() } 
    } 
} 

Trả lời

20

Mặc dù bạn đã gửi câu trả lời của riêng bạn, đây là một biến thể:

dir Leaflets -r | % { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } } 

Một số điểm:

  • dir là bí danh cho Get-ChildItem (và -r là viết tắt của -Recurse).
  • % là bí danh cho ForEach-Object.
  • -cne là so sánh phân biệt chữ hoa chữ thường. -ne bỏ qua các trường hợp khác biệt.
  • $ _ là cách bạn tham chiếu mục hiện tại trong vòng lặp ForEach-Object.
  • ren là bí danh cho Đổi tên mục.
  • FullName có lẽ được ưa thích vì nó đảm bảo bạn sẽ chạm vào đúng tệp.

Nếu bạn muốn không bao gồm các thư mục không bị đổi tên, bạn có thể bao gồm một cái gì đó như:

if ((! $_.IsPsContainer) -and $_.Name -cne $_.Name.ToLower()) { ... } 

Hy vọng rằng đây là hữu ích trong việc tiếp tục học hỏi và khám phá PowerShell.

10

Hãy nhớ rằng bạn có thể đường ống trực tiếp vào Rename-Item và sử dụng Scriptblocks với - NewName tham số (bởi vì nó cũng chấp nhận đầu vào đường ống) để đơn giản hóa nhiệm vụ này:

Get-ChildItem -r | Where {!$_.PSIsContainer} | 
        Rename-Item -NewName {$_.FullName.ToLower()} 

và với bí danh:

gci -r | ?{!$_.PSIsContainer} | rni -New {$_.FullName.ToLower()} 
+0

Cảm ơn. Và để thay đổi tên tệp, chúng tôi có thể sử dụng: gci. -recurse -force | ? {! $ _. PSIsContainer} | rni -New {$ _. Name.replace ("aaa", "bbb")} –

0

Đó là idomatic hơn trong PowerShell để sử dụng where thay vì if trong một đường ống:

 
gci -Recurse Leaflets | 
    ? { $_.Name -ne $_.Name.ToLower()) } | 
    % { ren -NewName $_.Name.ToLower() } 
1

tinh chỉnh nhẹ về điều này, nếu bạn chỉ muốn cập nhật tên các tập tin của một loại hình cụ thử này:

get-childitem *.jpg | foreach { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } } 

này sẽ chỉ chữ thường các file jpg trong thư mục của bạn và bỏ qua phần còn lại

1

Bạn cần phải tạm thời đổi tên chúng thành một cái gì đó khác sau đó đặt tên chúng trở lại tất cả các trường hợp thấp hơn.

$items = get-childitem -Directory -Recurse 

foreach ($item in $items) 
{ 

    if ($item.name -eq $item.name.ToLower()) 
    {  

     $temp = $item.FullName.ToLower() + "_" 
     $name = $item.FullName.ToLower() 
     ren $name $temp 

     ren $temp $name 
    } 
Các vấn đề liên quan