更改文本文件中的名称

更改文本文件中的名称

我有混合音乐项目,软件会生成每个项目中歌曲的 txt 文件列表。问题是,列表仅使用歌曲的前 36 个字符生成姓名每首歌曲。

我需要更正 txt 文件中的名称,以便它们与原始文件的名称相同,并且我的脚本可以使用列表复制文件。

我创建了一个脚本,分为两个块,其中在第一个块中我读取原始文件并生成一个与 txt 文件内名称同名的变量。

First block (what I managed to do):
读取 Original Musics 文件夹中的原始文件,并创建与 List.txt 文件中同名的变量。

Goal of the first block (what I couldn't do):
当此块中的变量名称与 List.txt 中的名称相同时,脚本会将 List.txt 中的名称更改为变量所关联的原始文件的全名。这样,第二个块就可以使用其中的正确名称读取 List.txt 文件。

注意:
可能出现Original Musics文件夹中有两个同名但不同版本的文件,在这种情况下,这两个文件的完整名称必须在要复制到目标文件夹的List.txt文件中。例如。

List.txt文件中的名称:
Got To Be Real (CM_Gex Bootleg Exten

原名(Original Musics文件夹中的全名):

Cheryl Lynn - Got To Be Real (CM_Gex Bootleg Extended SHORT Re Mix).mp3
Cheryl Lynn - Got To Be Real (CM_Gex Bootleg Extended LONG Re Mix).mp3

变量 $ShortOriginalSongName:

Got To Be Real (CM_Gex Bootleg Exten
Got To Be Real (CM_Gex Bootleg Exten

因为是同一个文件,区别在于一个是长版本,一个是短版本,两个全名都必须在List.txt文件中,也就是说,除了更改list.txt中的名称外,当文件相同时,脚本还必须在List.txt中包含原始的全名

脚本:

$files = "C:\Users\$env:username\Desktop\List.txt"
$location = "G:\Original Musics\"
$destination = "C:\Users\$env:username\Desktop\Copy Selected Musics\"


# First block:
Get-ChildItem -Recurse $location* -Include *.mp3 | % {
    $ShortOriginalSongName = $_.Basename.Split("-")[1].Trim();
    If ($ShortOriginalSongName.Length -gt 36) {$ShortOriginalSongName = $ShortOriginalSongName.Substring(0, 36)};
    };

# Second Block:
Get-Content $files | % {

  $result = gci -recurse "$location*$_" -Include *.mp3
  
  If($result) { 
    Add-Content $destination"AddList.txt" -Value $result.Fullname
    $musicName = $result.Name    
    $tot+=1       
    Write-Host -ForegroundColor Green "$musicName found on $location!"
    Write-Host "$musicName copied to $destination..."
    Copy-Item $result.FullName -Destination $destination\$($_.Name)
  } 
}

Second Block:
读取第一个块中歌曲正确名称生成的 List.txt 文件,并将原始文件复制到复制选定的音乐文件夹中。

答案1

您的代码中有很多对Get-ChildItemfor 的重复调用$Location,因此我建议创建一个将短名称与其关联文件关联起来的哈希表。

你想要:

  1. 整理你的文件:

    gci $Location *.mp3 -File -Recurse
    
  2. 创建一个由计算出的短名称和源 FileInfo 对象组成的自定义对象:

    [PSCustomObject]@{
        'ShortName' = $_.BaseName.Split('-')[-1].TrimStart().PadRIght(36).Substring(0, 36).TrimEnd()
        'FileInfo'  = $_
    }
    
  3. 按短名称对其进行分组(因为多个文件可以产生相同的短名称)。

因此我们从这个开始:

$files       = "C:\Users\$env:username\Desktop\List.txt"
$location    = "G:\Original Musics\"
$destination = "C:\Users\$env:username\Desktop\Copy Selected Musics\"


$ShortNameList = gci $Location *.mp3 -File -Recurse | %{
    [PSCustomObject]@{
        'ShortName' = $_.BaseName.Split('-')[-1].TrimStart().PadRight(36).Substring(0, 36).TrimEnd()
        'FileInfo'  = $_
}} | Group ShortName

然后将该对象转换为哈希表:

$ShortNameLookup = $ShortNameList | ForEach { $hash = @{} } {
    $hash.Add($_.Name , @( $_.Group.FileInfo ))
} { $hash }

然后核心处理使用中的每个条目$files作为哈希键:

Get-Content $files | %{
    If ( $FileInfo = $ShortNameLookup[$_] ) {
        Add-Content ( Join-Path $Destination 'AddList.txt' ) $FileInfo.FullName
        $FileInfo | %{
            Write-Host ( '"{0}" found in "{1}"' -f $_.BaseName , $_.DirectoryName)
        }
        $FileInfo | Copy-Item -Destination $Destination
    }
    Else { Write-Host "No files found that match '$_'." }
}

未经测试,但确信逻辑合理。希望上传代码——今晚晚些时候会添加注释。

相关内容