Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PowerShell中使用条件语句重命名文件_Powershell - Fatal编程技术网

如何在PowerShell中使用条件语句重命名文件

如何在PowerShell中使用条件语句重命名文件,powershell,Powershell,我试图重命名一个文件夹中的所有文件,但在不同的子文件夹中。应重命名文件,使其名称由foldername+原始文件名组成。我想知道您是否可以添加一个条件语句,以便在文件名已经包含文件夹名时,文件名不会更改。下面的代码执行重命名文件的功能,但不包含if语句 dir -recurse | Rename-Item -NewName {$_.Directory.Name + " - " + $_.Name} 下面的代码是一个关于我想象中的代码外观的示例: dir -recurse | if($_.Nam

我试图重命名一个文件夹中的所有文件,但在不同的子文件夹中。应重命名文件,使其名称由foldername+原始文件名组成。我想知道您是否可以添加一个条件语句,以便在文件名已经包含文件夹名时,文件名不会更改。下面的代码执行重命名文件的功能,但不包含if语句

dir -recurse | Rename-Item -NewName {$_.Directory.Name + " - " + $_.Name}
下面的代码是一个关于我想象中的代码外观的示例:

dir -recurse | if($_.Name -contains $_.Directory.Name) {Rename-Item -NewName {$_.Directory.Name + " - " + $_.Name}}
这应该做到:

$rootFolder = 'D:\test'
Get-ChildItem -Path $rootFolder -File -Recurse | ForEach-Object {
    $folder = $_.Directory.Name
    if (!($_.Name.StartsWith($folder))) { $_ | Rename-Item -NewName ('{0} - {1}' -f $folder, $_.Name) }
}
这应该做到:

$rootFolder = 'D:\test'
Get-ChildItem -Path $rootFolder -File -Recurse | ForEach-Object {
    $folder = $_.Directory.Name
    if (!($_.Name.StartsWith($folder))) { $_ | Rename-Item -NewName ('{0} - {1}' -f $folder, $_.Name) }
}
工作正常,但有一个备选方案,在概念上更简单,而且性能明显更好:

您可以利用这样一个事实:将未更改的文件名传递给
-NewName
是一个安静的禁止操作,因此您可以将所有逻辑放在
-NewName
脚本块中:

Get-ChildItem -File -Recurse |
  Rename-Item -NewName { 
    if ($_.Name -like ($_.Directory.Name + ' - *') { # already renamed
      $_.Name # no change
    }
    else { # rename
      $_.Directory.Name ' - ' + $_.Name
    }
  } -WhatIf
-WhatIf
预览重命名操作;删除它以执行实际重命名

与在脚本块中使用嵌套的
Rename Item
调用
ForEach对象
不同-这意味着对每个输入文件调用一次
Rename Item
-此解决方案使用单个管道和单个
Rename Item
调用,其中新名称(如果更改)是通过延迟绑定脚本块确定的-有关详细信息,请参阅。

效果很好,但有一个备选方案在概念上更简单,性能也明显更好:

您可以利用这样一个事实:将未更改的文件名传递给
-NewName
是一个安静的禁止操作,因此您可以将所有逻辑放在
-NewName
脚本块中:

Get-ChildItem -File -Recurse |
  Rename-Item -NewName { 
    if ($_.Name -like ($_.Directory.Name + ' - *') { # already renamed
      $_.Name # no change
    }
    else { # rename
      $_.Directory.Name ' - ' + $_.Name
    }
  } -WhatIf
-WhatIf
预览重命名操作;删除它以执行实际重命名


与在脚本块中使用嵌套的
Rename Item
调用
ForEach对象
不同-这意味着对每个输入文件调用一次
Rename Item
-此解决方案使用单个管道和单个
Rename Item
调用,其中新名称(如果更改)是通过延迟绑定脚本块确定的-有关详细信息,请参阅。

我尝试的方式与问题提出的方式非常接近。我希望我不必再加一个foreach

dir -recurse -file | & { 
  foreach ($i in $input) {
    if(-not ($i.Name.contains($i.Directory.Name))) {
      Rename-Item $i.fullname -NewName ($i.Directory.Name + ' - ' + $i.Name) -whatif 
    } 
  } 
}
还是像这样

dir -recurse -file | % { 
  if(-not ($_.Name.contains($_.Directory.Name))) {
    Rename-Item $_.fullname -NewName ($_.Directory.Name + ' - ' + $_.Name) -whatif 
  } 
}

我试着用一种接近提问方式的方式。我希望我不必再加一个foreach

dir -recurse -file | & { 
  foreach ($i in $input) {
    if(-not ($i.Name.contains($i.Directory.Name))) {
      Rename-Item $i.fullname -NewName ($i.Directory.Name + ' - ' + $i.Name) -whatif 
    } 
  } 
}
还是像这样

dir -recurse -file | % { 
  if(-not ($_.Name.contains($_.Directory.Name))) {
    Rename-Item $_.fullname -NewName ($_.Directory.Name + ' - ' + $_.Name) -whatif 
  } 
}

如果未从管道中读取语句,则可能重复
。改为使用Where Object
。您的意思是if-not。contains()…如果语句未从管道中读取,则可能重复
。改为使用Where Object
。您的意思是if-not。包含()。。。