这是我在 Stack Overflow 上的第一篇文章,我避免寻求帮助,而是尽可能多地自己解决这个问题。 我的脚本编写经验很少,但我想学习。 我选择了这个项目作为开始,感觉这个脚本的目标很快就失控了。

我拥有的是一个功能性的,可能非常臃肿的脚本,它只能完成我希望它为我做的一小部分。

这是我的任务,在我们 100% 手动完成之前 - 手动逐个文件:

我有非常重要的 MP3 文件,需要从 SD 卡复制并最终移动到定期备份的共享驱动器。

这些文件的文件名格式为 MMDDYYYYHHMMSS_RC-700R.mp3

我们将这些文件存储在自己的数据共享目录中,并按月份进一步组织,这让我尝试将其添加为脚本的一部分,但这是一个不太重要的功能。

我的目标是安全地将这些文件从 SD 卡中移出,重命名它们 - 删除文件的 TIME,但如果在同一日期制作了 2 个(或更多)文件以附加字母迭代计数。 我试图注释掉每一步,不仅让其他人阅读,而且让自己了解我在代码的每个部分中尝试完成的工作。

#Start by Clearing Host and Saving Transcript
Clear-Host
$date = Get-Date -Format 'dddd MM-dd-yyyy'
Start-Transcript -Path "F:\Script$date.txt" -NoClobber -Append

#Set locations - SD Card:Import
$Import = "C:\Users\Death\Desktop\Minutes"
$Source = "F:\Minutes\"
$Destination = "F:\Final\"

#Test if $Source Exists, if not Create directory for Files to be transferred to
if(!(Test-Path -Path $Source))  {  
    New-Item -ItemType directory -Path $Source
    Write-Host "Folder path has been created successfully at: " $Source    
    }
   else { 
   Write-Host "The given folder path $Source already exists"; 
   }
   #Test if $Destination exists and create if false
   if(!(Test-Path -Path $Destination))  {  
     New-Item -ItemType directory -Path $Destination
     Write-Host "Folder path has been created successfully at: $Destination "}
    else { 
    Write-Host "The given folder path $Destination already exists"; 
    }

   #Copy Items from $Import location
   Get-ChildItem -Path $Import -Filter *.mp3 | Copy-Item -Destination $Source
   #Rename Files adding Dashes between MM DD YYYY and HHMMSS
   Get-ChildItem -Path $Source -Filter *.mp3 | Rename-Item -NewName {$_.Name -Replace ('^\n*(\d{2})(\d{2})(\d{4})(\d{6}).(?:...)(\d{3})\w','TC $1-$2-$3-$4')}
   
   #Move files into $Destination\Year\Month created - Need to add


#Move files into $NewPath\Year\Month created
#Running in to problems with moving the files after they have been renamed - Likely due to 

Get-ChildItem -File -Path $Source -Filter '*.mp3' |
ForEach-Object {

    $Year = $_.LastWriteTime.Year
    $Month = $_.LastWriteTime.Month
    $Monthname = (Get-Culture).DateTimeFormat.GetMonthName($Month)
    $ArchDir = "$Destination\$Year\$Monthname\"

    if (-not (Test-Path -Path $ArchDir)) { New-Item -ItemType "directory" -Path $ArchDir | Out-Null }
    Move-Item -Path $Source\*.mp3 -Destination $ArchDir -Verbose
    }


#Would like to add a list of files renamed and where they moved to instead of just Enter to exit
Read-Host -Prompt "Press Enter to exit" 

我的目标的一小部分在此代码的其他版本中起作用,但这是我最实用的一个。

目前存在的问题:

  1. 我还没有想出如何在重命名文件并关闭 TIME 时安全地迭代在同一天创建的文件 - 因此,由于它目前正在运行,我将 TIME 保留在文件上,我正在手动删除它并添加任何字母需要的时候

  2. 它在第一个文件的月份将所有文件扔到 $Destination 中,并将所有文件放在那里(不是一个大问题,因为这是额外的)

我希望它列出每个移动操作以及任何错误。 它现在使用 $Source 和 $Destination 文件夹以及最终 GCI - 移动操作上的 -Verbose 来执行此操作。

在我证明脚本 100% 可用之前,我将脚本中的所有位置都放在本地机器上,以使我的老板满意。

我对文字墙感到抱歉,并提前感谢您的任何帮助。

#1楼 票数:2

这看起来过于复杂了。

对于文件部分,它可以像这样简单......根据您陈述的用例:

  1. 我的目标是安全地将这些文件从 SD 卡中移出,

  2. 重命名它们 - 删除文件的时间,

Clear-Host
$SourcePath = 'C:\Temp'
$TargetPath = 'C:\Temp\TempChild'

Get-ChildItem -Path $SourcePath -Filter '*.mp3' | 
ForEach {
    $FileName = $PSItem
    Try
    {
        If ((Get-Item -Path "$TargetPath\$($FileName.Name)" -ErrorAction Stop))
        {
            Rename-Item -Path "$TargetPath\$($PSItem.Name)" -NewName "$($FileName.Name -replace '\d+_')" -WhatIf
            Move-Item -Path $FileName.FullName -Destination $TargetPath -WhatIf
        }
    }
    Catch {Move-Item -Path $FileName.FullName -Destination $TargetPath -WhatIf}
}

# Results
<#
# When the file does not exists
What if: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3".

# When the file exists
What if: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\RC-M1234R.mp3".
What if: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3".
#>

您可以创建新路径,而无需使用 New-Item。 只需在复制/移动操作上使用 -Force 开关/参数即可。

Test-Path -Path "$TargetPath\test1" 
# Results
<#
False
#>

Get-ChildItem -Path $SourcePath -Filter '*.mp3' | 
Copy-Item -Destination "$TargetPath\test1" -Force -WhatIf
# Results
<#
What if: Performing the operation "Copy File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\test1".
#>

Get-ChildItem -Path $SourcePath -Filter '*.mp3' | 
Copy-Item -Destination "$TargetPath\test1" -Force 
Test-Path -Path "$TargetPath\test1" 
Get-ChildItem -Path $TargetPath -Filter '*.mp3'
# Results
<#
True
    Directory: C:\Temp\TempChild


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          4/8/2021   6:04 PM             39 04122021143000_RC-M12345R.mp3
-a----          4/8/2021   6:04 PM             39 04122021143000_RC-M1234R.mp3
#>

至于

  1. 但如果在同一日期制作了 2 个(或更多)文件,则按字母顺序进行迭代计数。

我不确定您为什么使用字母与数字。 由于 alpha 会将您限制为 26 个字母,然后您最终不得不将该字符串加倍。 数字当然,你可以只看数字并加1。

这就是我的意思,只需使用您的文件名与文件属性。 但是,您可以通过查看混合中的文件属性来执行相同的方法。

Clear-Host
$SourcePath = 'C:\Temp'
$TargetPath = 'C:\Temp\TempChild'

Get-ChildItem -Path $SourcePath -Filter '*.mp3' | 
ForEach {
    $FileName = $PSItem

    Try
    {
        If (
            -Not ((Get-ChildItem -Path $TargetPath -Filter $FileName.Name) -match "(?<=RC-M\d+R\d)") -and 
            ($FileName.Name -replace '_\.*') -match 
            ((Get-ChildItem -Path $TargetPath -Filter $FileName.Name)  -replace '_\.*')
        )
        {
            Rename-Item -Path "$TargetPath\$($FileName.Name)" -NewName "$(
                                                                            $FileName.Name -replace 'R\.', 'R1.'
                                                                         )" -ErrorAction Stop -WhatIf

            Move-Item -Path $FileName.FullName -Destination $TargetPath -Verbose -WhatIf
        }
    }
    Catch
    {
        $FileToIncrement = (
                                Get-ChildItem -Path $TargetPath | 
                                Where-Object -Property Name -Match ($FileName.BaseName -replace 'R\d+')
                           ).FullName 

        if($FileToIncrement -match "(?<=RC-M\d+R)(?<bv>\d+)")
        {
            Rename-Item -Path $FileToIncrement -NewName (
                                                            $FileToIncrement -replace "(?<=RC-M\d+R)(\d+)", 
                                                            ("{0:0000}" -f (([int]::Parse($matches.bv)+1)))
                                                        ) -Verbose -WhatIf

            Move-Item -Path $FileName.FullName -Destination $TargetPath -Verbose -WhatIf
        }
    }
}

# Results - when incrementer does not exist for the matched time string
<#
VERBOSE: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M12345R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M12345R1.mp3".
VERBOSE: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M12345R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M12345R.mp3".
VERBOSE: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R1.mp3".
VERBOSE: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3".
#>

# Results - when incrementer exists for the matched time string
<#
What if: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M12345R1.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M12345R0002.mp3".
What if: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M12345R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M12345R.mp3".
What if: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M1234R1.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R0002.mp3".
What if: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3".
#>

  ask by IchibanDeath translate from so

未解决问题?本站智能推荐:

2回复

PowerShell/Regex:重命名所有文件,修改编号顺序

我目前有一个包含数千个文件的目录。 每个文件在文件名中的某处都有_c04_或_c05_等。 我需要将所有这些文件重命名为_c004_或_c005_等。 唯一需要改变的是添加额外的零。 该字母将始终为c 。 我对正则表达式很陌生,我不知道搜索和替换这个字符串的正确方法。 到目前为止我已经编写了这
2回复

PowerShell批量替换特定字符并重命名文件扩展名

我需要批量重命名文件共享中的文件 包含特定字符,即波浪号~和 文件扩展名应使用大写字母或完全不使用。 目的是将波浪号替换为简单的- ,保留文件扩展名(如果有),但将其转换为小写字母。 我在查找文件的脚本的第一部分中取得了成功 $PATH = "\\<Fil
3回复

在CMD中以重命名和升序重命名文件

我知道这个问题已经有人问过,但我会再问一次。 有人可以告诉我如何在CMD中批量重命名和升序排列。 我已经尝试过在Powershell中重命名,但无济于事。 它只让我使用一次,我需要重命名另一个文件夹文件,但无济于事。 它没有让它重命名另一个文件夹中的文件。 这是我在Powershell
3回复

使用powershell将多个文件夹重命名为大写而不是文件

我正在使用 powershell,其中有多个文件夹,我需要将所有文件夹名称更改为大写,而不是仅文件文件夹。 我试过下面的代码 但是使用此代码它只更改文件名但我只想更改目录 例如 文件夹名(小写) 像这样(大写) 提前致谢
1回复

使用Powershell根据表重命名电子表格的文件名[关闭]

有没有一种方法可以根据其中包含的内容并使用数据表来重命名Excel文档。 更具体地说,我收到了50多个文件(每个文件都有一个通用的随机名称),我必须在订单号后对其进行重命名。 我必须手动打开文件以获得订单号,然后将文件重命名。 是否有可以在Powershell中运行的脚本或任何其他可以
1回复

正则表达式在批量文件重命名中不起作用

我在使用正则表达式时遗漏了一些东西,因为当我替换定义的字符串时,我的行有效。 我试过\\d和[0-9] 。 我忘记了什么? 原始FOOBAR_12345678-0001.csv 目标12345678.csv
1回复

逐步重命名文件名

我想通过在字符串前面加上前缀来重命名文件夹中的文件名。 我发现此Windows PowerShell脚本仅以字符串为前缀: 我根本不熟悉这种脚本语言。 所以我尝试了这个: 当然失败了。 我该如何实现?
1回复

批量重命名文件,具体取决于文件所在的子文件夹

我正在尝试重命名一堆子文件夹中的一堆文件。 我希望他们有一个“前缀”,该前缀与放置它们的子文件夹相对应。 例: 主文件夹: 子文件夹1 子文件夹2 子文件夹3 Subfolder1中的所有文件都应重命名为“ Subfold