Выход файла в Powershell без расширения

Вот что я до сих пор:

Get-ChildItem "C:\Folder" | Foreach-Object {$_.Name} > C:\Folder\File.txt

Когда вы открываете вывод сверху, File.txt, вы видите это:

file1.txt
file2.mpg
file3.avi
file4.txt

Как мне получить вывод, чтобы он удалял расширение и отображал только это:

file1
file2
file3
file4

Спасибо заранее!

ИЗМЕНИТЬ

Подумал об этом с помощью молодчиков ниже меня. Я закончил использование:

Get-ChildItem "C:\Folder" | Foreach-Object {$_.BaseName} > C:\Folder\File.txt

Ответ 1

Get-ChildItem "C:\Folder" | Select BaseName > C:\Folder\File.txt

Ответ 2

Передайте имя файла в метод GetFileNameWithoutExtension чтобы удалить расширение:

Get-ChildItem "C:\Folder" | '
    ForEach-Object { [System.IO.Path]::GetFileNameWithoutExtension($_.Name) } '
    > C:\Folder\File.txt

Я хотел прокомментировать ответ @MatthewMartin, который разделяет имя входящего файла на . символ и возвращает первый элемент результирующего массива. Это будет работать для имен с нуля или единицы . , но дает неверные результаты для чего-либо еще:

  • file.ext1.ext2 file
  • powershell.exe is good for me. Let me explain to thee..doc powershell.exe is good for me. Let me explain to thee..doc урожаи powershell

Причина в том, что он возвращает все до первого . когда действительно должно быть все до последнего . , Чтобы это исправить, после того, как мы разделим имя на сегменты . Мы берем каждый сегмент, кроме последнего, и соединяем их вместе, разделив их . , В случае, если имя не содержит . мы возвращаем полное имя.

ForEach-Object {
    $segments = $_.Name.Split('.')

    if ($segments.Length -gt 1) {
        $segmentsExceptLast = $segments | Select-Object -First ($segments.Length - 1)

        return $segmentsExceptLast -join '.'
    } else {
        return $_.Name
    }
}

Более эффективный подход заключается в том, чтобы пройтись по названию символ за символом. Если текущий символ является . , вернуть имя до, но не включая текущий символ. Если нет . найден, вернуть полное имя.

ForEach-Object {
    $name = $_.Name;

    for ($i = $name.Length - 1; $i -ge 0; $i--) {
        if ($name[$i] -eq '.') {
            return $name.Substring(0, $i)
        }
    }

    return $name
}

Класс [String] уже предоставляет метод для выполнения этой же задачи, поэтому приведенное выше можно уменьшить до...

ForEach-Object {
    $i = $_.Name.LastIndexOf([Char] '.');

    if ($i -lt 0) {
        return $_.Name
    } else {
        return $_.Name.Substring(0, $i)
    }
}

Все три из этих подходов будут работать для имен с нулем, одним или несколькими . персонажи, но, конечно, они гораздо более многословны, чем другие ответы тоже. Фактически, LastIndexOf() - это то, что GetFileNameWithoutExtension() использует для внутреннего использования, а то, что использует BaseName использует преимущества уже вычисленного расширения и функционально аналогично вызову $_.Name.Substring().

Ответ 3

И теперь для версии FileInfo, так как все остальные избили меня до решения Path.GetFileNameWithoutExtension.

Get-ChildItem "C:\" | `
where { ! $_.PSIsContainer } | `
Foreach-Object {([System.IO.FileInfo]($_.Name)).Name.Split('.')[0]}

Ответ 4

Используйте свойство BaseName вместо свойства Name:

Get-ChildItem "C:\Folder" | Select-Object BaseName > C:\Folder\File.txt