Menghapus jalur dan ekstensi dari nama file di PowerShell

99

Saya memiliki serangkaian string yang merupakan jalur lengkap ke file. Saya hanya ingin menyimpan nama file, tanpa ekstensi file dan jalur utama. Jadi dari ini:

c:\temp\myfile.txt

untuk

myfile

Saya sebenarnya tidak melakukan iterasi melalui direktori, dalam hal ini sesuatu seperti basenameproperti PowerShell dapat digunakan, tetapi saya berurusan dengan string saja.

larryq
sumber
7
banyak jawaban tidak memperhitungkan bagian kedua dari pertanyaan tersebut. Ketika Get-Item, Get-ChildItem, atau aliasnya ls, dir, gi, gci digunakan, file dari string yang diuji harus ada . Ketika kita memeriksa rangkaian string dan tidak melakukan iterasi melalui direktori , harus diasumsikan bahwa file tersebut tidak perlu ada di komputer tempat skrip ini akan dijalankan.
papo

Jawaban:

110

Ada metode .NET yang berguna untuk itu:

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

Jauh lebih mudah daripada yang saya pikirkan untuk mengatasi masalah menampilkan jalur lengkap, direktori, nama file, atau ekstensi file.

$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

bentuk lain:

$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)
Leonardo
sumber
25
Alangkah baiknya jika di samping setiap contoh di cuplikan kode teratas Anda menunjukkan dengan tepat teks apa yang akan dikembalikan.
anjing mematikan
Contoh di mana saya tidak tahu nama file .csr, tetapi saya tahu ada file: $csr = Get-ChildItem -Path "$($domain.FullName)/*.csr"kemudianWrite-Host "fileName: $($csr.Basename)"
Scott Pelak
46

Terinspirasi oleh jawaban @ walid2mi:

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

Harap diperhatikan: ini hanya berfungsi jika file yang diberikan benar-benar ada .

CodeFox
sumber
1
Ini adalah cara termudah untuk mendapatkan nama file untuk satu file.
marisks
6
Ini mengasumsikan file tersebut ada. Menghapus ekstensi dari nama file seharusnya tidak bergantung pada itu. Bagaimana jika Anda membuat file berdasarkan nama file di mana file tersebut tidak ada? Path adalah string dan harus diperlakukan sebagai string, tidak dianggap sebagai file yang sudah ada.
Antony Booth
29

atau

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

atau

"c:\temp\myfile.txt".split('\.')[-2]
walid2mi.dll
sumber
9
Contoh kedua tidak bekerja terlalu baik dengan sesuatu seperti - "C: \ Downloads \ ReSharperSetup.7.0.97.60.msi" .split ('\.') [- 2]
Keith Hill
24

Anda dapat menggunakan basename properti

PS II> ls *.ps1 | select basename
walid2mi.dll
sumber
7
OP mengatakan: Saya sebenarnya tidak melakukan iterasi melalui direktori.
CB.
1
Sangat berguna untuk saya!
iheartcsharp
5

@ Keith ,

di sini opsi lain:

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]
walid2mi.dll
sumber
4

Diberikan sembarang string jalur, berbagai metode statis pada objek System.IO.Path memberikan hasil berikut.

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

Berikut adalah kode yang menghasilkan keluaran di atas.

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

Menulis dan menguji skrip yang menghasilkan di atas mengungkap beberapa keanehan tentang bagaimana PowerShell berbeda dari C #, C, C ++, bahasa skrip perintah Windows NT, dan hampir semua hal lain yang saya alami.

David A. Gray
sumber
3

Dimulai dengan PowerShell 6, Anda mendapatkan nama file tanpa ekstensi seperti:

split-path c:\temp\myfile.txt -leafBase
René Nyffenegger
sumber
Ini benar di PowerShell 6. Tidak ada LeafBase di standar rawa 5.1
finlaybob
1
Terima kasih atas infonya, saya telah memperbarui jawaban yang sesuai. Apa itu rawa ?
René Nyffenegger
2
Apologies :) dari mana saya berasal (Inggris), "Bog Standard" adalah istilah slang untuk sesuatu yang benar-benar biasa, versi "vanilla".
finlaybob
2

Skrip ini mencari di folder dan sub folder dan mengganti nama file dengan menghapus ekstensinya

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

    Foreach-Object {

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

    }
pengguna12386990
sumber
2

Memperluas jawaban René Nyffenegger, bagi mereka yang tidak memiliki akses ke PowerShell versi 6.x, kami menggunakan Jalur Terpisah, yang tidak menguji keberadaan file:

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

Ini mengembalikan " myfile.txt ". Jika kita tahu bahwa nama file tidak memiliki titik di dalamnya, kita dapat membagi string dan mengambil bagian pertama:

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

atau

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

Ini mengembalikan " myfile ". Jika nama file mungkin menyertakan titik, untuk amannya, kita bisa menggunakan yang berikut:

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

Ini mengembalikan " myfile.txt.config ". Di sini saya lebih suka menggunakan Substring () daripada Replace () karena ekstensi yang didahului oleh titik juga bisa menjadi bagian dari nama, seperti dalam contoh saya. Dengan menggunakan Substring kami mengembalikan nama file tanpa ekstensi seperti yang diminta.

Papa Ccompis
sumber
1
terima kasih banyak atas jawaban ini, sangat lengkap dan membantu saya
Sam
1

Ini satu tanpa tanda kurung

[io.fileinfo] 'c:\temp\myfile.txt' | % basename
Steven Penny
sumber
1

Ini dapat dilakukan dengan memisahkan string beberapa kali.

#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

Berikut kode tanpa komentar:

$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
OneOfThePetes
sumber
1
Kenapa susah sekali?
Jaroslav Štreit
2
Tidak berfungsi jika nama file berisi lebih dari satu titik, misalnya MyApp.exe.config
Joe