我有一个文件README.TXT
。如果我发出以下命令:
PS> Get-Item ReadMe.txt
...然后它返回“ReadMe.txt”。我想找出磁盘上文件的实际名称,包括大小写。如何让它返回“README.TXT”?
我之所以问这个问题,是因为我想追踪 Windows 上不区分大小写的文件名与 Unix 系统上区分大小写的文件之间的问题,并且我想获得 Windows 系统上实际使用的大小写。
更多详情:我有一份文件列表(存储在一个.CSPROJ
文件中),这些文件的大小写与存储在磁盘上的大小写不同。我想确保它们匹配。例如:如果文件.CSPROJ
显示“ReadMe.txt”,但磁盘上的文件为“README.TXT”,有时在 Visual Studio 中编辑该文件会将文件重写为“ReadMe.txt”,这会让 Perforce 感到困惑,因为它区分大小写,文件名不再具有它所期望的大小写。我想编写一个脚本来发现不匹配的文件名,以便在导致问题之前对它们采取措施。
答案1
以下是我的想法:
function Get-ActualFileName($file) {
$parent = Split-Path $file
$leaf = Split-Path -Leaf $file
$result = Get-ChildItem $parent | where { $_ -like $leaf }
$result.Name
}
答案2
以下 PowerShell 函数基于另一位开发人员为 C# 提供的优雅解决方案,网址为https://stackoverflow.com/a/11436327/854680。
因为获取子项未被使用,快多了,当调用此函数几十次或几百次时,就会产生区别。
function Get-FileNameTrueCase {
Param (
[parameter(Mandatory=$true)]
[string]
$DirOrFile
)
if (-not ( (Test-Path $DirOrFile -PathType Leaf) -or (Test-Path $DirOrFile -PathType Container) ) ) {
# File or directory not found
return $DirOrFile
}
$TruePath = "";
foreach ($PathPart in $DirOrFile.Split("\")) {
if ($TruePath -eq "") {
$TruePath = $PathPart.ToUpper() + "\";
continue;
}
$TruePath = [System.IO.Directory]::GetFileSystemEntries($TruePath, $PathPart)[0];
}
return $TruePath;
}
答案3
无需指定确切的名称,只需使用通配符:
PS> Get-Item ReadMe.tx?
这应该返回README.TXT
答案4
我能想到的最快的方法是用 *\ 替换所有斜杠,然后调用 Get-Item,并确保没有重复,选择与您指定的不区分大小写的斜杠相同的斜杠。
$Path = Get-Item "$($Path.TrimEnd('\/') -replace "(?<!:)(\\|/)", '*$1')*" |
Where { $_.FullName -ieq $Path } | Convert-Path