Как переименовать файлы с помощью условного оператора в PowerShell - PullRequest
1 голос
/ 16 октября 2019

Я пытаюсь переименовать все файлы, расположенные в одной папке, но в разных подпапках. Файлы должны быть переименованы так, чтобы их имя состояло из foldername + оригинальное имя файла. Мне интересно, если вы могли бы добавить условные операторы, чтобы имя файла не изменилось, если имя файла уже содержит имя папки. Приведенный ниже код выполняет функцию переименования файлов, но не содержит оператора if.

dir -recurse | Rename-Item -NewName {$_.Directory.Name + " - " + $_.Name}

Приведенный ниже код является примером того, как, по моему мнению, будет выглядеть код:

dir -recurse | if($_.Name -contains $_.Directory.Name) {Rename-Item -NewName {$_.Directory.Name + " - " + $_.Name}}

Ответы [ 3 ]

3 голосов
/ 16 октября 2019

Это должно сделать это:

$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) }
}
2 голосов
/ 16 октября 2019

Ответ Тео работает хорошо, но есть альтернатива , которая концептуально проще и работает заметно лучше:

Вы можете воспользоваться тем, что прохождение неизменное имя файла для -NewName - это quiet no-op , поэтому вы можете поместить всю свою логику в блок сценария -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 предварительный просмотр операция переименования;удалите его для фактического переименования.

Вместо использования ForEach-Object вызова с вложенным Rename-Item вызовом в своем блоке сценария - это означает, что Rename-Item вызывается один раз для каждого вводаfile - это решение использует одиночный конвейер с single Rename-Item, где новое имя (если изменено) определяется с помощью delay-bind блок сценария - подробности см. в этом ответе .

0 голосов
/ 16 октября 2019

Я пытался сделать это так, как был задан вопрос. Хотелось бы, чтобы мне не пришлось добавлять другой 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 
  } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...