在Powershell中从文件名中删除路径和扩展名


99

我有一系列字符串,这些字符串是文件的完整路径。我只想保存文件名,而没有文件扩展名和前导路径。所以从这个:

c:\temp\myfile.txt

myfile

我实际上并没有遍历目录,在这种情况下basename可以使用诸如powershell的属性之类的东西,但是我只是在处理字符串。


7
许多答案都没有考虑到问题的第二部分。使用Get-Item,Get-ChildItem或它们的别名ls,dir,gi,gci时,来自测试字符串的文件必须存在。当我们检查一系列字符串而不是遍历目录时,必须假定这些文件在运行此脚本的计算机上不需要存在。
papo

Answers:


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
如果在最上面的代码片段中的每个示例旁边都显示了将返回什么文本,那将是很好的。
致命狗

我不知道.csr文件名但知道文件存在的示例:$csr = Get-ChildItem -Path "$($domain.FullName)/*.csr"然后Write-Host "fileName: $($csr.Basename)"
Scott Pelak

46

受到@ walid2mi 的答案的启发:

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

请注意:这仅在给定文件确实存在时才有效。


1
这是获取单个文件文件名的最简单方法。
2016年

6
这假设文件存在。从文件名中删除扩展名不应该依赖于此。如果要基于不存在的文件名创建文件怎么办?该路径是一个字符串,应将其视为字符串,而不应假定为现有文件。
安东尼·布斯,

29

要么

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

要么

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

9
第二个示例不适用于类似“ C:\ Downloads \ ReSharperSetup.7.0.97.60.msi” .split('\。')[-2]
Keith Hill

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

这在Powershell 6中是正确的。沼泽标准5.1中没有LeafBase
finlaybob

1
感谢您提供信息,我已经相应地更新了答案。什么是沼泽
勒内Nyffenegger

2
抱歉:)我来自(英国),“ Bog Standard”是一个something语,指的是完全普通的东西,是“ vanilla”版本。
finlaybob

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 ”。在这里,我更喜欢使用Substring()而不是Replace(),因为带扩展名的句点也可以是名称的一部分,如我的示例所示。通过使用Substring,我们将按要求返回不带扩展名的文件名。


1
非常感谢你对这个答案,这是非常完整的,它帮助我
山姆


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Štreit19年

2
如果文件名包含多个句点,则不起作用,例如MyApp.exe.config
Joe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.