似乎 Powershell 的 .Extension
方法无法识别双重扩展名。
结果,像这样:
Get-ChildItem -Path:. | Rename-Item -NewName {
'{0}{1}' -f ($_.BaseName -replace '\.', '_'), $_.Extension
}
最终将 file.1.tar.gz
重命名为 file_1_tar.gz
,而我想要 file_1.tar.gz
。
只是一个疏忽? 还是可以缓解?
最佳答案
这是预期的行为。
这是 Microsoft Doc 的引述。关于 [System.IO.Path]::GetExtension
方法,它似乎与其他类似功能和 Powershell Cmdlet 共享相同的实现逻辑。
This method obtains the extension of path by searching path for a period (.), starting with the last character in path and continuing toward the first character. If a period is found before a DirectorySeparatorChar or AltDirectorySeparatorChar character, the returned string contains the period and the characters after it; otherwise, String.Empty is returned.
您当然可以通过为 tar.gz 和其他双重扩展创建异常来缓解这种情况,方法是使用字典来定义应被视为双重异常的内容。这是缓解的示例。
Get-ChildItem -Path 'C:\temp' | % {
$BaseName = $_.BaseName
$Extension = $_.Extension
if ($_.FullName.EndsWith('.tar.gz')) {
$BaseName = $_.BaseName.SubString(0,$_.BaseName.Length -4)
# I used the full name as reference to preserve the case on the filenames
$Extension = $_.FullName.Substring($_.FullName.Length - 7)
}
Rename-Item -Path $_.FullName -NewName (
'{0}{1}' -f ($BaseName -replace '.', '_'), $Extension
)
}
请注意,因为我只有 .tar.gz
,所以我实际上并没有使用字典,但如果您有多个双扩展类型,最好的方法是通过循环应用此方法每个扩展名以查看它是否匹配。
以这个为例,它循环遍历一个数组来检查多个双重扩展
# Outside of the main loop to avoid redeclaring each time.
$DoubleExtensionDict = @('.tar.gz', '.abc.def')
Get-ChildItem -Path 'C:\temp' | % {
$BaseName = $_.BaseName
$Extension = $_.Extension
Foreach ($ext in $DoubleExtensionDict) {
if ($_.FullName.EndsWith($ext)) {
$FirstExtLength = ($ext.split('.')[1]).Length
$BaseName = $_.BaseName.SubString(0, $_.BaseName.Length - $FirstExtLength -1)
$Extension = $_.FullName.Substring($_.FullName.Length - 7)
break
}
}
Rename-Item -Path $_.FullName -NewName (
'{0}{1}' -f ($BaseName -replace '.', '_'), $Extension
)
}
引用资料
关于powershell - 检索具有双文件扩展名的 $_.Extension,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70370928/