web-dev-qa-db-ja.com

Powershellでファイルの名前を小文字に変更

Powershell 2.0を使用して、一連のファイルの名前を再帰的に変更しようとしています。ディレクトリ構造は次のようになります。

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

次のコマンドを使用しています。

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

ファイルの名前を変更しているようですが、サブディレクトリについて不平を言っています。

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

Robocopyを使用して毎月データをリロードしますが、ディレクトリは変更されないため、手動で名前を変更できます。 get-childrenにサブディレクトリ(find Leaflets -type f ...など)をスキップさせる方法はありますか?

ありがとう。

PDATE:問題はすでにすべて小文字になっているファイルにあるようです。コマンドを次のように変更してみました:

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

しかし、Powershellは、ifがコマンドレットや関数などではないと文句を言います。get-childitemの出力をifステートメントにパイプできますか?

PDATE 2:これは機能します:

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

あなたはすでにあなた自身の答えを投稿していますが、ここにバリエーションがあります:

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

いくつかのポイント:

  • dirGet-ChildItemのエイリアスです(-rは-Recurseの略です)。
  • ForEach-Objectのエイリアスです。
  • -cneは大文字と小文字を区別する比較です。 -ne大文字と小文字の違いを無視します。
  • $ _は、ForEach-Objectループで現在のアイテムを参照する方法です。
  • renRename-Itemのエイリアスです。
  • FullNameは、適切なファイルに確実にアクセスできるため、おそらく推奨されます。

ディレクトリの名前変更を除外したい場合は、次のようなものを含めることができます。

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

これがPowerShellの学習と探索を継続するのに役立つことを願っています。

24
Goyuix

Rename-Itemに直接パイプし、-NewNameパラメーターでScriptblocksを使用して(パイプライン入力も受け入れるため)、このタスクを簡略化できることに注意してください。

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

およびエイリアスあり:

gci -r | ?{!$_.PSIsContainer} | rni -New {$_.FullName.ToLower()}
15
Keith Hill

特定のタイプのファイルの名前のみを更新したい場合は、これを少し調整してみてください。

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

これにより、フォルダ内のjpgファイルのみが小文字になり、残りは無視されます

2
ddools

Rename-Item、配管、ループ、およびWindowsファイルシステムの動作の性質により、前述の回答には多くの問題があります。残念ながら、私が見つけた最も単純な(ここでは読みやすさのためにエイリアスを使用しない)解決策すべてのファイルとフォルダーの名前を変更する特定のフォルダー内を小文字に変更するのはこれです:

Get-ChildItem -Path "/Path/To/You/Folder" -Recurse | Where{ $_.Name -cne $_.Name.ToLower() } | ForEach-Object { $tn="$($_.Name)-temp"; $tfn="$($_.FullName)-temp"; $nn=$_.Name.ToLower(); Rename-Item -Path $_.FullName -NewName $tn; Rename-Item -Path $tfn -NewName $nn -Force; Write-Host "New Name: $($nn)";}
2
masi

一時的に名前を別の名前に変更してから、すべて小文字に戻す必要があります。

$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
   }
1
Derek Smalls

PowerShellでは、パイプラインでwhereの代わりにifを使用する方が理想的です。

 gci-Recurseリーフレット| 
? {$ _。Name-ne $_。Name.ToLower())} | 
%{ren -NewName $_。Name.ToLower()} 
0
Jay Bazuzi

ジェイ・バズジからの回答に対する小さいながらも重要な訂正。 -cne(大文字と小文字が区別されない)演算子は、where-partが何かを返す必要がある場合に使用する必要があります。

さらに、Pathパラメーターが存在する必要があることがわかりました。このバージョンは私のセットアップで機能しました:

gci -Recurse | 
    ? { $_.Name -cne $_.Name.ToLower() } | 
    % { ren $_.Name -NewName $_.Name.Tolower()  }
0
JensGC