PowerShell의 파일 이름에서 경로 및 확장자 제거


99

파일에 대한 전체 경로 인 일련의 문자열이 있습니다. 파일 확장자와 선행 경로없이 파일 이름 만 저장하고 싶습니다. 그래서 이것으로부터 :

c:\temp\myfile.txt

myfile

나는 실제로 디렉토리를 반복하는 것이 아니라 powershell의 basename속성 과 같은 것을 사용할 수있는 경우가 아니라 문자열 만 처리합니다.


7
많은 답변이 질문의 두 번째 부분을 고려하지 않습니다. Get-Item, Get-ChildItem 또는 해당 별칭 ls, dir, gi, gci가 사용되는 경우 테스트 된 문자열의 파일 이 존재해야합니다 . 우리가 확인 될 때 문자열의 일련 가 아닌 디렉토리를 통해 반복 , 해당 파일이 스크립트가 실행됩니다 컴퓨터에 존재하지 않아도 가정해야합니다.
papo jul.

답변:


110

이를위한 편리한 .NET 메서드가 있습니다.

C:\PS> [io.path]::GetFileNameWithoutExtension("c:\temp\myfile.txt")
myfile

93

전체 경로, 디렉토리, 파일 이름 또는 파일 확장자를 표시하는 문제를 해결하기 위해 생각했던 것보다 훨씬 쉽습니다.

$PSCommandPath
(Get-Item $PSCommandPath ).Extension
(Get-Item $PSCommandPath ).Basename
(Get-Item $PSCommandPath ).Name
(Get-Item $PSCommandPath ).DirectoryName
(Get-Item $PSCommandPath ).FullName
$ConfigINI = (Get-Item $PSCommandPath ).DirectoryName+"\"+(Get-Item $PSCommandPath ).BaseName+".ini"
$ConfigINI

다른 형태 :

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
split-path -parent $PSCommandPath
Split-Path $script:MyInvocation.MyCommand.Path
split-path -parent $MyInvocation.MyCommand.Definition
[io.path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name)

25
상단 코드 스 니펫의 각 예제 옆에 정확히 어떤 텍스트가 반환되는지 보여 주면 좋을 것입니다.
deadlydog 2017

.csr 파일 이름을 모르지만 파일이 있다는 것을 알고있는 예 : $csr = Get-ChildItem -Path "$($domain.FullName)/*.csr"thenWrite-Host "fileName: $($csr.Basename)"
Scott Pelak

46

@ walid2mi 의 답변 에서 영감을 얻었 습니다.

(Get-Item 'c:\temp\myfile.txt').Basename

참고 : 이것은 주어진 파일이 실제로 존재하는 경우에만 작동 합니다 .


1
이것은 단일 파일의 파일 이름을 얻는 가장 쉬운 방법입니다.
marisks

6
이것은 파일이 존재한다고 가정합니다. 파일 이름에서 확장자를 제거하는 것은 그것에 의존해서는 안됩니다. 파일이 존재하지 않는 파일 이름을 기반으로 파일을 만드는 경우 어떻게해야합니까? 경로는 문자열이며 기존 파일로 간주되지 않고 문자열로 처리되어야합니다.
Antony Booth

29

또는

([io.fileinfo]"c:\temp\myfile.txt").basename

또는

"c:\temp\myfile.txt".split('\.')[-2]

9
두 번째 예는 같은과 너무 잘 작동하지 않습니다 - "C : \ 다운로드 \ ReSharperSetup.7.0.97.60.msi".split을 [- 2] ( '\.')
키이스 힐

24

basename 속성을 사용할 수 있습니다.

PS II> ls *.ps1 | select basename

7
OP는 다음과 같이 말합니다. 실제로 디렉토리를 반복하지 않습니다.
CB.

1
나에게 매우 유용합니다!
iheartcsharp

5

@Keith ,

여기에 또 다른 옵션 :

PS II> $f="C:\Downloads\ReSharperSetup.7.0.97.60.msi"

PS II> $f.split('\')[-1] -replace '\.\w+$'

PS II> $f.Substring(0,$f.LastIndexOf('.')).split('\')[-1]

4

임의의 경로 문자열이 주어지면 System.IO.Path 개체에 대한 다양한 정적 메서드는 다음과 같은 결과를 제공합니다.

strTestPath = C : \ Users \ DAG \ Documents \ Articles_2018 \ NTFS_File_Times_in_CMD \ PathStringInfo.ps1
GetDirectoryName = C : \ Users \ DAG \ Documents \ Articles_2018 \ NTFS_File_Times_in_CMD
GetFileName = PathStringInfo.ps1
GetExtension = .ps1
GetFileNameWithoutExtension = PathStringInfo

다음은 위의 출력을 생성 한 코드입니다.

[console]::Writeline( "strTestPath                 = {0}{1}" ,
                      $strTestPath , [Environment]::NewLine );
[console]::Writeline( "GetDirectoryName            = {0}" ,
                      [IO.Path]::GetDirectoryName( $strTestPath ) );
[console]::Writeline( "GetFileName                 = {0}" ,
                      [IO.Path]::GetFileName( $strTestPath ) );
[console]::Writeline( "GetExtension                = {0}" ,
                      [IO.Path]::GetExtension( $strTestPath ) );
[console]::Writeline( "GetFileNameWithoutExtension = {0}" ,
                      [IO.Path]::GetFileNameWithoutExtension( $strTestPath ) );

위의 스크립트를 작성하고 테스트 한 결과 PowerShell이 ​​C #, C, C ++, Windows NT 명령 스크립팅 언어 및 내가 경험 한 다른 모든 것과 어떻게 다른지에 대한 몇 가지 단점을 발견했습니다.


3

PowerShell 6부터 다음과 같이 확장자가없는 파일 이름을 얻습니다.

split-path c:\temp\myfile.txt -leafBase

이것은 더 LeafBase 5.1 늪지 표준이 없다 PowerShell을 6에서 올
finlaybob가

1
정보 주셔서 감사합니다. 그에 따라 답변을 업데이트했습니다. 습지 란 무엇입니까 ?
René Nyffenegger

2
사과 :) 내가 (영국)에서 왔을 때, "Bog Standard"는 완전히 평범한 것을 "바닐라"버전에 대한 속어입니다.
finlaybob 2011

2

이 스크립트는 폴더 및 하위 폴더를 검색하고 확장자를 제거하여 파일 이름을 바꿉니다.

    Get-ChildItem -Path "C:/" -Recurse -Filter *.wctc |

    Foreach-Object {

      rename-item $_.fullname -newname $_.basename

    }

2

René Nyffenegger의 답변을 확장하여 PowerShell 버전 6.x에 액세스 할 수없는 사용자를 위해 파일 존재 여부를 테스트하지 않는 Split Path를 사용합니다.

Split-Path "C:\Folder\SubFolder\myfile.txt" -Leaf

" myfile.txt "를 반환합니다 . 파일 이름에 마침표가 없다는 것을 알면 문자열을 분할하고 첫 번째 부분을 취할 수 있습니다.

(Split-Path "C:\Folder\SubFolder\myfile.txt" -Leaf).Split('.') | Select -First 1

또는

(Split-Path "C:\Folder\SubFolder\myfile.txt" -Leaf).Split('.')[0]

이것은 " myfile "을 반환합니다 . 파일 이름에 마침표가 포함 된 경우 안전을 위해 다음을 사용할 수 있습니다.

$FileName = Split-Path "C:\Folder\SubFolder\myfile.txt.config.txt" -Leaf
$Extension = $FileName.Split('.') | Select -Last 1
$FileNameWoExt = $FileName.Substring(0, $FileName.Length - $Extension.Length - 1)

" myfile.txt.config "를 반환합니다 . 여기에서는 Replace () 대신 Substring ()을 사용하는 것을 선호합니다. 마침표가 앞에 오는 확장자도 내 예제에서와 같이 이름의 일부일 수 있기 때문입니다. Substring을 사용하여 요청 된 확장자없이 파일 이름을 반환합니다.


1
이 답변에 대해 대단히 감사합니다. 매우 완전하며 도움이되었습니다
Sam

1

여기에 괄호가없는 것이 있습니다.

[io.fileinfo] 'c:\temp\myfile.txt' | % basename

1

이것은 문자열을 몇 번 분할하여 수행 할 수 있습니다.

#Path
$Link = "http://some.url/some/path/file.name"

#Split path on "/"
#Results of split will look like this : 
# http:
#
# some.url
# some
# path
# file.name
$Split = $Link.Split("/")

#Count how many Split strings there are
#There are 6 strings that have been split in my example
$SplitCount = $Split.Count

#Select the last string
#Result of this selection : 
# file.name
$FilenameWithExtension = $Split[$SplitCount -1]

#Split filename on "."
#Result of this split : 
# file
# name
$FilenameWithExtensionSplit = $FilenameWithExtension.Split(".")

#Select the first half
#Result of this selection : 
# file
$FilenameWithoutExtension = $FilenameWithExtensionSplit[0]

#The filename without extension is in this variable now
# file
$FilenameWithoutExtension

주석이없는 코드는 다음과 같습니다.

$Link = "http://some.url/some/path/file.name"
$Split = $Link.Split("/")
$SplitCount = $Split.Count
$FilenameWithExtension = $Split[$SplitCount -1]
$FilenameWithExtensionSplit = $FilenameWithExtension.Split(".")
$FilenameWithoutExtension = $FilenameWithExtensionSplit[0]
$FilenameWithoutExtension

1
왜 그렇게 어려운가요?
Jaroslav Štreit

2
파일 이름에 마침표가 두 개 이상 포함 된 경우 작동하지 않습니다. 예 : MyApp.exe.config
Joe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.