Powershell'de dosya adından yolu ve uzantıyı kaldırma


100

Dosyalara tam yol olan bir dizi dizem var. Dosya uzantısı ve ana yol olmadan sadece dosya adını kaydetmek istiyorum. Yani bundan:

c:\temp\myfile.txt

-e

myfile

Aslında bir dizinde yineleme yapmıyorum, bu durumda powershell'in basenameözelliği gibi bir şey kullanılabilir, bunun yerine yalnızca dizelerle uğraşıyorum.


7
birçok cevap sorunun ikinci bölümünü hesaba katmıyor. Get-Item, Get-ChildItem veya takma adları ls, dir, gi, gci kullanıldığında, test edilen dizedeki dosyanın var olması gerekir . Bir dizi diziyi kontrol ettiğimizde ve bir dizinde yinelemediğimizde , bu dosyaların bu betiğin çalıştırılacağı bilgisayarda bulunmasına gerek olmadığı varsayılmalıdır.
papo

Yanıtlar:


111

Bunun için kullanışlı bir .NET yöntemi var:

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

94

Tam yolu, dizini, dosya adını veya dosya uzantısını görüntüleme sorununu ele almayı düşündüğümden çok daha kolay.

$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

diğer formlar:

$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
En üstteki kod parçacığındaki her örneğin yanında tam olarak hangi metnin döndürüleceğini göstermeniz iyi olurdu.
deadlydog

.Csr dosya adını bilmediğim, ancak bir dosyanın var olduğunu bildiğim örnek: $csr = Get-ChildItem -Path "$($domain.FullName)/*.csr"o zamanWrite-Host "fileName: $($csr.Basename)"
Scott Pelak

46

Bir esinlenerek cevap @ walid2mi arasında:

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

Lütfen dikkat: bu sadece verilen dosya gerçekten varsa işe yarar .


1
Bu, tek bir dosya için dosya adı almanın en kolay yoludur.
marisks

6
Bu, dosyanın var olduğunu varsayar. Dosya adından bir uzantının kaldırılması buna bağlı olmamalıdır. Ya dosyanın var olmadığı bir dosya adına dayalı bir dosya oluşturuyorsanız? Yol bir dizedir ve varolan bir dosya olduğu varsayılmadan bir dizge olarak ele alınmalıdır.
Antony Booth

29

veya

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

veya

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

9
İkinci örnek - "C: \ Downloads \ ReSharperSetup.7.0.97.60.msi" .split ('\.') [- 2]
Keith Hill

24

basename özelliğini kullanabilirsiniz

PS II> ls *.ps1 | select basename

7
OP diyor ki: Aslında bir dizinde yineleme yapmıyorum.
CB.

1
Benim için çok faydalı!
iheartcsharp

5

@Keith ,

burada başka bir seçenek:

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

Herhangi bir rasgele yol dizesi verildiğinde, System.IO.Path nesnesindeki çeşitli statik yöntemler aşağıdaki sonuçları verir.

strTestPath = C: \ Kullanıcılar \ DAG \ Belgeler \ Makaleler_2018 \ NTFS_File_Times_in_CMD \ PathStringInfo.ps1
GetDirectoryName = C: \ Kullanıcılar \ DAG \ Belgeler \ Makaleler_2018 \ NTFS_File_Times_in_CMD
GetFileName = PathStringInfo.ps1
GetExtension = .ps1
GetFileNameWithoutExtension = PathStringInfo

Yukarıdaki çıktıyı oluşturan kod aşağıdadır.

[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 ) );

Yukarıdakileri oluşturan betiği yazmak ve test etmek, PowerShell'in Windows NT komut dosyası yazma dili olan C #, C, C ++ 'dan ve deneyimim olan hemen hemen her şeyden nasıl farklı olduğuna dair bazı tuhaflıkları ortaya çıkardı.


3

PowerShell 6'dan başlayarak, dosya adını şu şekilde uzantı olmadan alırsınız:

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

Bu powershell 6'da doğrudur. 5.1 bataklık standardında LeafBase yok
finlaybob

1
Bilgi için teşekkürler, cevabı buna göre güncelledim. Nedir bataklık ?
René Nyffenegger

2
Özür dilerim :) (İngiltere) nereli olduğum için, "Bataklık Standardı" tamamen sıradan bir şeyin argo terimidir, "vanilya" versiyonu.
finlaybob

2

Bu komut dosyası bir klasörde ve alt klasörlerde arama yapar ve uzantılarını kaldırarak dosyaları yeniden adlandırır.

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

    Foreach-Object {

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

    }

2

René Nyffenegger'ın cevabını genişleterek, PowerShell sürüm 6.x'e erişimi olmayanlar için, dosya varlığını test etmeyen Split Path kullanıyoruz:

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

Bu, " dosyam.txt " dosyasını döndürür . Dosya adında nokta olmadığını bilirsek, dizeyi bölebilir ve ilk kısmı alabiliriz:

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

veya

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

Bu, " dosyam " ı döndürür . Dosya adı nokta içeriyorsa, emin olmak için aşağıdakileri kullanabiliriz:

$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)

Bu, " dosyam.txt.config " dosyasını döndürür . Burada Replace () yerine Substring () kullanmayı tercih ediyorum, çünkü bir noktadan önce gelen uzantı da benim örneğimde olduğu gibi adın bir parçası olabilir. Substring'i kullanarak, istendiği gibi dosya adını uzantı olmadan döndürürüz.


1
bu cevap için çok teşekkür ederim, çok eksiksiz ve bana yardımcı oldu
Sam


1

Bu, dizeyi birkaç kez bölerek yapılabilir.

#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

İşte yorumsuz kod:

$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
Neden bu kadar zor yol?
Jaroslav Štreit

2
Dosya adı birden fazla nokta içeriyorsa çalışmaz, örneğin MyApp.exe.config
Joe,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.