Veja o que eu criei:
function Get-ActualFileName($file) {
$parent = Split-Path $file
$leaf = Split-Path -Leaf $file
$result = Get-ChildItem $parent | where { $_ -like $leaf }
$result.Name
}
Eu tenho um arquivo README.TXT
. Se eu emitir o seguinte comando:
PS> Get-Item ReadMe.txt
... então retorna "ReadMe.txt". Eu quero descobrir o nome real do arquivo no disco, incluindo o caso. Como obtenho para retornar "README.TXT"?
Eu pergunto porque estou tentando rastrear um problema com nomes de arquivos sem distinção entre maiúsculas e minúsculas no Windows versus arquivos que diferenciam maiúsculas de minúsculas em uma caixa Unix, e quero que o caso atual seja usado na caixa do Windows.
Mais detalhes: Eu tenho uma lista de arquivos (armazenados em um arquivo .CSPROJ
) que estão em um caso diferente daqueles armazenados no disco. Eu quero ter certeza de que eles combinem. Por exemplo: se o arquivo .CSPROJ
diz "ReadMe.txt", mas o arquivo no disco é "README.TXT", às vezes, editando o arquivo no Visual Studio reescreve o arquivo como "ReadMe.txt", que confunde o Perforce, porque é sensível a maiúsculas e minúsculas, e o nome do arquivo não tem mais o caso esperado. Eu quero escrever um script que identifique os nomes de arquivos incompatíveis, para que eu possa fazer algo sobre eles antes que cause um problema.
A maior parte do trabalho do sistema de arquivos no PowerShell é feita por algumas classes .NET no namespace System.IO. Se você conhece o caminho (como no seu exemplo, você navegou para o local do sistema de arquivos onde seu arquivo de assunto está localizado), então você poderia usar algo como
(get-item $pwd).GetFiles('readme.txt')
Como as classes .NET básicas diferenciam maiúsculas de minúsculas, a saída resultante dos nomes dos arquivos também fará distinção entre maiúsculas e minúsculas.
Para referência, no exemplo, você está chamando o método GetFiles do objeto System.IO.DirectoryInfo que representa o diretório de trabalho atual ($ pwd). Você pode mudar isso para apontar para o diretório que contém o arquivo que você precisa para confirmar o case.
As propriedades Name, BaseName e FullName devem todas refletir o case apropriado.
A maneira mais rápida que posso pensar é substituir todas as barras por * \ e depois chamar Get-Item, e para ter certeza de que você não obterá dupes, escolha aquela que não diferencia maiúsculas de minúsculas da que você especificou. / p>
$Path = Get-Item "$($Path.TrimEnd('\/') -replace "(?<!:)(\|/)", '*$1')*" |
Where { $_.FullName -ieq $Path } | Convert-Path
Em vez de especificar o nome exato, basta usar um curinga:
PS> Get-Item ReadMe.tx?
isso deve retornar README.TXT
Aqui está minha abordagem rápida e suja (sem validação):
Function Resolve-PathName { [CmdletBinding()]
Param(
[Parameter(ValueFromPipelinebyPropertyName,ValueFromPipeline,Mandatory)]
[Alias("Fullname")]
[string] $File,
[switch] $Cygpath
) Process {
$cur = $File
$stack = New-Object System.Collections.Stack
while ( $cur.length -gt 0) {
$stack.Push( (split-path $cur -Leaf) )
$cur = split-path $cur
}
$cur = get-item ($stack.pop())
while ( $stack.Count -gt 0) {
$cur = $cur | Get-ChildItem -Filter ($stack.Pop())
}
if ($Cygpath) {
cygpath $cur.Fullname
} else {
$cur.Fullname
}
}}
Tags powershell