gpt4 book ai didi

powershell - 如何在 Powershell Pipeline 中多次使用 $_(子字符串方法)

转载 作者:行者123 更新时间:2023-12-02 23:07:28 25 4
gpt4 key购买 nike

我正在尝试编写一个自动化程序,以便我可以给出如下所述的输入并获得指示的输出,并且我正在使用 Powershell 来执行此操作。

INPUT : Song name in the format given below
Artist Name - Song Name.mp3

OUTPUT : Rename the song file in the format given below
Song Name - Artist Name.Mp3

我知道有用于此的 OTS 工具,但我正在尝试使用 PowerShell 作为更大解决方案的一部分来执行此操作。

我有单行 PowerShell cmdlet 来获取项目,然后重命名它们。
所以我尝试了这个:

Get-ChildItem *.mp3 | Rename-Item -NewName {$_.Name.Substring($_.Name.IndexOf("-")+2,  $_.Name.IndexOf(".")) +" - " + $_.Name.Substring(0, ($_.Name.IndexOf("-"))) + ".mp3"}

这就是问题所在。子字符串部分中的第二个 IndexOf 获得一个空值,因为它在同一(子字符串)操作中被使用了两次。
$_.Name.Substring($_.Name.IndexOf("-")+2,  $_.Name.IndexOf("."))

这似乎是 PowerShell 的事情。以下面的行为例:
Get-ChildItem *.mp3 | Select-Object {$_.Name.Substring($_.Name.IndexOf("-")+2)}
Get-ChildItem *.mp3 | Select-Object {$_.Name.Substring($_.Name.IndexOf(".mp3"))}

当它们分开时,Ps 为每次运行提供一个输出。但是,如果我同时运行两个 cmdlet,则只有第一行给出输出,第二行返回 NULL。

如何获得以下逻辑的输出(我在此处进行选择只是为了进行故障排除,因为我不想在故障排除时实际重命名)
Get-ChildItem *.mp3 | Select-Object {$_.Name.Substring($_.Name.IndexOf("-")+2, $_.Name.IndexOf(".mp3"))}

我可以使用变量和连接字符串,但如果可能的话,尽量将过程保持在一行而不编写自定义代码/模块。

最佳答案

你的问题的根源是你的Substring表达。如果您将其从管道中断开片刻,您会看到正在吞噬的错误...

PS> $s = "my artist - my song.mp3"
PS> $s.Substring($s.IndexOf("-") + 2, $s.IndexOf("."))
Exception calling "Substring" with "2" argument(s): "Index and length must refer to a location within the string.
Parameter name: length"
At line:1 char:1
+ $s.Substring($s.IndexOf("-") + 2, $s.IndexOf("."))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ArgumentOutOfRangeException

问题是 Substring需要 startIndexlength参数,但你试图给它一个 startIndexendIndex .结果是您的新名称是一个空字符串,因为在管道内引发了异常。

你可以用正则表达式来解决这个问题——比如:

PS> $s = "my artist - my song.mp3"
PS> $matches = [regex]::Match($s, "(?<artist>.*) - (?<song>.*).mp3")
PS> $newname = $matches.Groups["song"].Value + " - " + $matches.Groups["artist"].Value + ".mp3"
PS> $newname
my song - my artist.mp3

如果你把它放回你的管道,你会得到:

Get-ChildItem *.mp3 | Rename-Item -NewName {
$matches = [regex]::Match($_.Name, "(?<artist>.*) - (?<song>.*).mp3")
$matches.Groups["song"].Value + " - " + $matches.Groups["artist"].Value + ".mp3"
}

但是玩一下 Select-Object在您 promise 重命名整个音乐库之前:-)

关于powershell - 如何在 Powershell Pipeline 中多次使用 $_(子字符串方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58785905/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com