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.


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

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)

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 .


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]

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

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]

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.


3

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

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

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

    }

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.


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

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

1
Kenapa susah sekali?
Jaroslav Štreit

2
Tidak berfungsi jika nama file berisi lebih dari satu titik, misalnya MyApp.exe.config
Joe
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.