การลบพา ธ และนามสกุลออกจากชื่อไฟล์ใน powershell


103

ฉันมีชุดของสตริงซึ่งเป็นเส้นทางแบบเต็มไปยังไฟล์ ฉันต้องการบันทึกเฉพาะชื่อไฟล์โดยไม่มีนามสกุลไฟล์และพา ธ นำหน้า จากสิ่งนี้:

c:\temp\myfile.txt

ถึง

myfile

ฉันไม่ได้ทำซ้ำผ่านไดเร็กทอรีซึ่งในกรณีbasenameนี้สามารถใช้คุณสมบัติของ powershell ได้ แต่ฉันกำลังจัดการกับสตริงเพียงอย่างเดียว


7
คำตอบจำนวนมากไม่ได้คำนึงถึงส่วนที่สองของคำถาม เมื่อได้รับรายการ Get-ChildItem หรือนามแฝงของพวกเขา LS ผบ, กูเกิล, GCI มีการใช้ไฟล์จากสตริงการทดสอบที่จะต้องมีอยู่ เมื่อเราตรวจสอบชุดของสตริงและไม่ได้วนซ้ำผ่านไดเร็กทอรีต้องถือว่าไฟล์เหล่านั้นไม่จำเป็นต้องมีอยู่ในคอมพิวเตอร์ที่จะเรียกใช้สคริปต์นี้
papo

คำตอบ:



97

ง่ายกว่าที่คิดในการแก้ปัญหาการแสดงพา ธ ไดเร็กทอรีชื่อไฟล์หรือนามสกุลไฟล์

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

27
จะเป็นการดีถ้าข้างแต่ละตัวอย่างในข้อมูลโค้ดด้านบนคุณแสดงให้เห็นว่าข้อความใดจะถูกส่งกลับ
Deadlydog

ตัวอย่างที่ฉันไม่ทราบชื่อไฟล์. csr แต่ฉันรู้ว่ามีไฟล์อยู่: $csr = Get-ChildItem -Path "$($domain.FullName)/*.csr"แล้วWrite-Host "fileName: $($csr.Basename)"
Scott Pelak

47

แรงบันดาลใจจากคำตอบของ @ walid2mi:

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

หมายเหตุ:งานนี้เฉพาะในกรณีที่ไฟล์ที่ได้รับมีอยู่จริงๆ


1
นี่เป็นวิธีที่ง่ายที่สุดในการรับชื่อไฟล์สำหรับไฟล์เดียว
marisks

7
ถือว่ามีไฟล์อยู่ การลบนามสกุลออกจากชื่อไฟล์ไม่ควรขึ้นอยู่กับสิ่งนั้น จะเกิดอะไรขึ้นถ้าคุณสร้างไฟล์โดยใช้ชื่อไฟล์ที่ไม่มีไฟล์อยู่ พา ธ เป็นสตริงและควรถือว่าเป็นสตริงโดยไม่ถือว่าเป็นไฟล์ที่มีอยู่
Antony Booth

30

หรือ

([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 ไม่มี LeafBase ในมาตรฐาน bog 5.1
finlaybob

1
ขอบคุณสำหรับข้อมูลฉันได้อัปเดต anwer ให้แล้ว bogคืออะไร?
René Nyffenegger

2
ขอโทษ :) ฉันมาจากที่ไหน (สหราชอาณาจักร) "Bog Standard" เป็นคำแสลงของบางสิ่งที่ธรรมดาโดยสิ้นเชิงคือเวอร์ชัน "วานิลลา"
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 Štreit

2
ใช้ไม่ได้หากชื่อไฟล์มีมากกว่าหนึ่งช่วงเวลาเช่น MyApp.exe.config
Joe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.