переименуйте имя файла, удалив временную метку после расширения файла (.csv или .xlsx) - PullRequest
0 голосов
/ 28 января 2019

Мне нужен сценарий PowerShell, который будет переименовывать несколько файлов из папки

Образцы имен файлов:

1234_ABC_20190125_1600.csv.20190126_053415 
12345_ABC_20190125_1600.csv.20190126_0534156 
1234_ABC_20190125_1600.xlsx.20190126_0534156 
1234_ABC_20190125_1600.xlsx.20190126_0534156

Поскольку метка времени не соответствует, я не могу использовать длину.Сценарий должен быть в состоянии определить расширение файла (оно может быть введено пользователями) и удалить все после этого.

Желаемые имена файлов:

1234_ABC_20190125_1600.csv
12345_ABC_20190125_1600.csv
1234_ABC_20190125_1600.xlsx
1234_ABC_20190125_1600.xlsx

В настоящее время я использовал длину.Поскольку длина метки времени не согласована, я всегда должен изменять скрипт.

Мой текущий код:

Write-Host

$Path = Read-Host -Prompt 'Input the file path'
$char = Read-Host -Prompt 'Input number of last character you want to remove'

Get-ChildItem "$Path" | rename-item -newname { $_.name.substring(0,$_.name.length-"$char") }

powershell -noexit 

Как изменить имя файла с переменной длиной?

1 Ответ

0 голосов
/ 28 января 2019

Начните с метода Path.ChangeExtension , затем удалите символ конечной точки с помощью метода String.TrimEnd :

'1234_ABC_20190125_1600.csv.20190126_053415',
'12345_ABC_20190125_1600.csv.20190126_0534156',
'1234_ABC_20190125_1600.xlsx.20190126_0534156',
'1234_ABC_20190125_1600.xlsx.20190126_0534156' |
ForEach-Object { [System.IO.Path]::ChangeExtension($_, '').TrimEnd('.') }

Вывод:

1234_ABC_20190125_1600.csv
12345_ABC_20190125_1600.csv
1234_ABC_20190125_1600.xlsx
1234_ABC_20190125_1600.xlsx

Обновление:

Заменить

Get-ChildItem "$Path" | ForEach-Object { [System.IO.Path]::ChangeExtension($_, '').TrimEnd('.') }

на

Get-ChildItem $path | Rename-Item -WhatIf -NewName {[System.IO.Path]::ChangeExtension($_.FullName, '').TrimEnd('.')}`

Обратите внимание на -WhatIf параметр, который отображает сообщение, описывающее действие команды, вместо ее выполнения.Чтобы переименовать, удалите этот параметр.

Обновление № 2:

Get-ChildItem -Path $path -File -Filter *.????????_?????? |
  ForEach-Object {
    $n = $t = [System.IO.Path]::ChangeExtension($_.FullName, '').TrimEnd('.')
    $p = Split-Path -Path $n -Parent
    $l = [System.IO.Path]::GetFileNameWithoutExtension($n)
    $x = [System.IO.Path]::GetExtension($n)
    $i = 1
    while( Test-Path -Path $t -PathType Any ) {
      $t = Join-Path -Path $p -ChildPath "${l}_${i}${x}"
      $i++
    }
    Rename-Item -LiteralPath $_.FullName -NewName $t -WhatIf
  }

Чтобы переименовать, удалите параметр -WhatIf или переписайте его как -WhatIf:$false.

Обновление № 3:

Add-Type -AssemblyName 'Microsoft.VisualBasic'
$type = [Microsoft.VisualBasic.Interaction]
for() {
  $path = $type::InputBox('Enter the path of interest:', 'Path request')
  if( [string]::IsNullOrEmpty($path) ) { break }
  if( Test-Path -LiteralPath $path -PathType Container ) {
    Get-ChildItem -LiteralPath $path -File -Filter *.????????_?????? |
      ForEach-Object {
        $n = $t = [System.IO.Path]::ChangeExtension($_.FullName, '').TrimEnd('.')
        $p = Split-Path -LiteralPath $n
        $l = [System.IO.Path]::GetFileNameWithoutExtension($n)
        $x = [System.IO.Path]::GetExtension($n)
        $i = 1
        while( Test-Path -LiteralPath $t -PathType Any ) {
          $t = Join-Path -LiteralPath $p -ChildPath "${l}_${i}${x}"
          $i++
        }
        Rename-Item -LiteralPath $_.FullName -NewName $t -WhatIf
      }
    $result = $type::MsgBox('Want to rerun the script again?',
                            'RetryCancel, Question', 'Request to rerun')
  } else {
    $result = $type::MsgBox(
                "The path entered is not valid.`nWant to re-enter the path?",
                'RetryCancel, Question', 'Request to re-enter'
              )
  }
  if( $result -eq 'Cancel' ) { break }
}

Я думаю, вы можете избавиться от -NoExit.

Обновление № 4:

Add-Type -AssemblyName 'Microsoft.VisualBasic'
$type = [Microsoft.VisualBasic.Interaction]
for() {
  $path = $type::InputBox('Enter the path of interest:', 'Path request')
  if( [string]::IsNullOrEmpty($path) ) { break }
  if( Test-Path -LiteralPath $path -PathType Container ) {
    $result = $type::MsgBox("Do you want to rename?`nSelect Cancel to exit.",
                            'YesNoCancel, Question',
                            'Request of the value of the -WhatIf parameter')
    if( $result -eq 'Cancel' ) { break }
    $whatif = $result -eq 'No'
    $renamed = 0
    Get-ChildItem -LiteralPath $path -File -Filter *.????????_?????? |
      ForEach-Object {
        $n = $t = [System.IO.Path]::ChangeExtension($_.FullName, '').TrimEnd('.')
        $p = Split-Path -LiteralPath $n
        $l = [System.IO.Path]::GetFileNameWithoutExtension($n)
        $x = [System.IO.Path]::GetExtension($n)
        $i = 1
        while( Test-Path -LiteralPath $t -PathType Any ) {
          $t = Join-Path -LiteralPath $p -ChildPath "${l}_${i}${x}"
          $i++
        }
        Rename-Item -LiteralPath $_.FullName -NewName $t -WhatIf:$whatif
        $renamed++
      }
    if( $whatif -or $renamed -eq 0 ) { $prompt = 'Nothing has been done' }
    else {
      if( $renamed -eq 1 ) { $prompt = '1 file was' }
      else { $prompt = "${renamed} files were" }
      $prompt = "${prompt} renamed"
    }
    $prompt = "${prompt}.`nWant to rerun the script again?"
    $result = $type::MsgBox($prompt, 'RetryCancel, Question', 'Request to rerun')
  } else {
    $result = $type::MsgBox(
                "The path entered is not valid.`nWant to re-enter the path?",
                'RetryCancel, Question', 'Request to re-enter'
              )
  }
  if( $result -eq 'Cancel' ) { break }
}

Добавлен запрос значения параметра -WhatIf и отображение информации о количестве переименованных файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...