Xóa đường dẫn và phần mở rộng khỏi tên tệp trong powershell


99

Tôi có một loạt các chuỗi là đường dẫn đầy đủ đến các tệp. Tôi chỉ muốn lưu tên tệp, không có phần mở rộng tệp và đường dẫn đầu. Vì vậy, từ điều này:

c:\temp\myfile.txt

đến

myfile

Tôi không thực sự lặp lại qua một thư mục, trong trường hợp đó, một cái gì đó như thuộc basenametính của powershell có thể được sử dụng, mà là tôi đang xử lý các chuỗi một mình.


6
nhiều câu trả lời không tính đến phần thứ hai của câu hỏi. Khi Get-Item, Get-ChildItem hoặc các bí danh ls, dir, gi, gci của chúng được sử dụng, tệp từ chuỗi được kiểm tra phải tồn tại . Khi chúng tôi đang kiểm tra một chuỗi chuỗi và không lặp lại qua một thư mục , thì phải giả định rằng những tệp đó không cần tồn tại trên máy tính nơi tập lệnh này sẽ được chạy.
papo

Câu trả lời:


109

Có một phương pháp .NET tiện dụng cho việc đó:

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

93

Cách dễ dàng hơn tôi nghĩ để giải quyết vấn đề hiển thị đầy đủ đường dẫn, thư mục, tên tệp hoặc phần mở rộng tệp.

$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

các chứng từ khác:

$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
Sẽ thật tuyệt nếu bên cạnh mỗi ví dụ trong đoạn mã trên cùng, bạn hiển thị chính xác văn bản nào sẽ được trả về.
deaddog

Ví dụ mà tôi không biết tên tập tin .csr, nhưng tôi biết một tập tin tồn tại: $csr = Get-ChildItem -Path "$($domain.FullName)/*.csr"sau đóWrite-Host "fileName: $($csr.Basename)"
Scott Pelak

46

Lấy cảm hứng từ câu trả lời của @ walid2mi:

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

Xin lưu ý: điều này chỉ hoạt động nếu tệp đã cho thực sự tồn tại .


1
Đây là cách dễ nhất để lấy tên tệp cho một tệp.
marisks

5
Điều này giả sử tệp tồn tại. Việc xóa phần mở rộng khỏi tên tệp không phụ thuộc vào điều đó. Điều gì sẽ xảy ra nếu bạn đang tạo tệp dựa trên tên tệp mà tệp không tồn tại? Đường dẫn là một chuỗi và phải được coi là một chuỗi, không được giả định là một tệp hiện có.
Antony Booth

29

hoặc là

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

hoặc là

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

9
Ví dụ thứ hai không làm việc quá tốt với một cái gì đó giống như - "C: \ Downloads \ ReSharperSetup.7.0.97.60.msi" .split [- 2] ( '\').
Keith Hill

24

bạn có thể sử dụng basename bất động sản

PS II> ls *.ps1 | select basename

7
OP nói: Tôi không thực sự lặp lại một thư mục.
CB.

1
Rất hữu ích cho tôi!
iheartcsharp

5

@Keith ,

ở đây một tùy chọn khác:

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

Với bất kỳ chuỗi đường dẫn tùy ý nào, các phương thức tĩnh khác nhau trên đối tượng System.IO.Path cho kết quả sau.

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

Sau đây là đoạn mã tạo ra kết quả ở trên.

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

Viết và kiểm tra tập lệnh tạo ra ở trên đã khám phá ra một số điều kỳ lạ về cách PowerShell khác với C #, C, C ++, ngôn ngữ kịch bản lệnh Windows NT và mọi thứ khác mà tôi có bất kỳ kinh nghiệm nào.


3

Bắt đầu với PowerShell 6, bạn nhận được tên tệp không có phần mở rộng như sau:

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

Đây là chính xác trong PowerShell 6. Không có LeafBase trong tiêu chuẩn bog 5.1
finlaybob

1
Cảm ơn vì thông tin, tôi đã cập nhật anwer cho phù hợp. Sag là gì?
René Nyffenegger

2
Xin lỗi :) nơi tôi đến từ (Vương quốc Anh), "Bog Standard" là một thuật ngữ tiếng lóng chỉ một thứ hoàn toàn bình thường, một phiên bản "vani".
finlaybob

2

Tập lệnh này tìm kiếm trong một thư mục và các thư mục con và đổi tên các tệp bằng cách xóa phần mở rộng của chúng

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

    Foreach-Object {

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

    }

2

Mở rộng theo câu trả lời của René Nyffenegger, đối với những người không có quyền truy cập vào PowerShell phiên bản 6.x, chúng tôi sử dụng Đường dẫn tách, không kiểm tra sự tồn tại của tệp:

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

Điều này trả về " myfile.txt ". Nếu chúng ta biết rằng tên tệp không có dấu chấm trong đó, chúng ta có thể tách chuỗi và lấy phần đầu tiên:

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

hoặc là

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

Điều này trả về " myfile ". Nếu tên tệp có thể bao gồm các dấu chấm, để an toàn, chúng tôi có thể sử dụng như sau:

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

Điều này trả về " myfile.txt.config ". Ở đây tôi thích sử dụng Chuỗi con () thay vì Replace () vì phần mở rộng đứng trước dấu chấm cũng có thể là một phần của tên, như trong ví dụ của tôi. Bằng cách sử dụng Substring, chúng tôi trả về tên tệp mà không có phần mở rộng như được yêu cầu.


1
cảm ơn bạn rất nhiều vì câu trả lời này, nó rất đầy đủ và nó đã giúp tôi
Sam

1

Đây là một trong những không có dấu ngoặc đơn

[io.fileinfo] 'c:\temp\myfile.txt' | % basename

1

Điều này có thể được thực hiện bằng cách tách chuỗi một vài lần.

#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

Đây là mã không có bình luận:

$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
Sao khó quá vậy?
Jaroslav Štreit

2
Không hoạt động nếu tên tệp chứa nhiều hơn một dấu chấm, ví dụ: MyApp.exe.config
Joe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.