Получить имя файла в случае, сохраненном на диске?

Одна вещь мы опасающийся - то, что все файлы журнала существуют и могут быть записаны в. Configtest не ловит проблемы с созданием или записью в файлы журнала, так, чтобы мог предотвратить Ваш сервер, перезапускающий правильно, и корректные перезапуски, кажется, не предотвращают это.

7
задан 28 September 2013 в 15:52
7 ответов

Вот что я придумал:

function Get-ActualFileName($file) {
    $parent = Split-Path $file
    $leaf = Split-Path -Leaf $file

    $result = Get-ChildItem $parent | where { $_ -like $leaf }
    $result.Name
}
3
ответ дан 2 December 2019 в 23:40

Основная часть файловой системы работает в PowerShell выполняется некоторыми классами .NET в пространстве имен System.IO. Если вы знаете путь (например, в вашем примере вы перешли в то место файловой системы, где находится ваш предметный файл), вы можете использовать что-то вроде

(get-item $pwd).GetFiles('readme.txt')

Поскольку базовые классы .NET чувствительны к регистру, результирующий вывод имен ваших файлов также будет чувствителен к регистру.

Для справки, в примере вы вызываете метод GetFiles объекта System.IO.DirectoryInfo, который представляет текущий рабочий каталог ($ pwd). Вы можете изменить это так, чтобы указывать на каталог, содержащий файл, в котором вам нужно подтвердить регистр.

Все свойства Name, BaseName и FullName должны отражать правильный регистр.

Дополнительная информация о методе GetFiles.

]
1
ответ дан 2 December 2019 в 23:40

Самый быстрый способ, который я могу придумать, - это заменить все косые черты на * \ и затем вызвать Get-Item, а чтобы убедиться, что вы не получаете дубликатов, выберите тот, который без учета регистра равен на тот, который вы указали.

$Path = Get-Item "$($Path.TrimEnd('\/') -replace "(?<!:)(\\|/)", '*$1')*" |
           Where { $_.FullName -ieq $Path } | Convert-Path
0
ответ дан 2 December 2019 в 23:40

Вместо того, чтобы указывать точное имя, просто используйте подстановочный знак:

PS> Get-Item ReadMe.tx?

это должно вернуть README .TXT

0
ответ дан 2 December 2019 в 23:40

Вот мой быстрый и грязный (без проверки ) подход:

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
    }
}}
0
ответ дан 2 December 2019 в 23:40

Следующая функция PowerShell основана на элегантном решении другого разработчика для C # по адресу https://stackoverflow.com/a/11436327/854680 .

Потому что ] Get-ChildItem не используется, он намного быстрее , что имеет значение при вызове этой функции десятки или сотни раз.

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;
}
2
ответ дан 2 December 2019 в 23:40

Ответ разобью на две части. 1) Если вас интересует только регистр имени файла и 2) Если вам важен регистр полного пути к файлу.

1. Регистр имени файла

Самый простой способ заставить Powershell выдавать вам правильный регистр имени файла — это выполнить поиск по имени файла. Мы можем добиться этого, используя класс символов RegEx (набор допустимых символов) для первой буквы имени файла.

Для поиска ReadMe.txt можно использовать [R]eadMe.txt. Класс символов RegEx обычно используется для нескольких возможных символов, но в этом случае мы просто используем один, чтобы всегда получать одно совпадение:

Get-Item [R]eadMe.txt | Select Name

Приведенное выше возвращает имя файла с правильным регистром:

README.TXT

​​Если имя файла предоставляется динамически или просматривается, вы можете использовать следующий простой оператор RegEx, чтобы окружить первые символы скобками:

"ReadMe.txt" -replace "^(.)", '[$1]'

Это возвращает:

[R]eadMe.txt

Пример использования для получения имени файла с правильным регистром:

$filename = "ReadMe.txt"
Get-Item ($filename -replace "^(.)", '[$1]') | Select Name

Приведенный выше пример возвращает имя файла с правильным регистром:

README.TXT

2. Полный путь к файлу

Основная концепция здесь остается той же, что и в первой части.У нас будет Powershell, который даст нам правильный регистр всех сегментов полного пути к файлу, заставив его искать каждый сегмент.

Как и в нашем предыдущем подходе, самый простой способ сделать это — заключить первый символ каждого сегмента в квадратные скобки.

Если имя файла известно, например:

c:\WINDOWS\systeM32\driverS\ETC\hosTS

Вы можете получить правильный регистр для полного пути, введя класс символов RegEx (набор допустимых символов) для первой буквы каждого сегмента:

Get-Item c:\[W]INDOWS\[s]ysteM32\[d]riverS\[E]TC\[h]osTS | Select FullName

Это в моей системе возвращает полный путь и имя файла с правильным регистром:

C:\Windows\System32\drivers\etc\hosts

Если полный путь к файлу динамически передается или просматривается, вы можете просто использовать следующий оператор RegEx для автоматического заключения первого символа каждого сегмента в квадратные скобки:

$FullFilePath = "c:\WINDOWS\systeM32\driverS\ETC\hosts"
$FullFilePath -replace "(\\|/)(.)", '$1[$2]'

Это возвращает:

c:\[W]INDOWS\[s]ysteM32\[d]riverS\[E]TC\[h]osts

Пример использования для получения полного пути к файлу с правильным регистром:

$FullFilePath = "c:\WINDOWS\systeM32\driverS\ETC\hosts"
Get-Item ($FullFilePath -replace "(\\|/)(.)", '$1[$2]') | Select FullName

Приведенное выше возвращает полный путь к файлу с правильным регистром case:

C:\Windows\System32\drivers\etc\hosts

0
ответ дан 4 April 2021 в 03:24

Теги

Похожие вопросы