Pfad und Erweiterung aus dem Dateinamen in Powershell entfernen


99

Ich habe eine Reihe von Zeichenfolgen, die vollständige Pfade zu Dateien sind. Ich möchte nur den Dateinamen ohne die Dateierweiterung und den führenden Pfad speichern. Also daraus:

c:\temp\myfile.txt

zu

myfile

Ich iteriere nicht wirklich durch ein Verzeichnis. In diesem Fall könnte so etwas wie die basenameEigenschaft von Powershell verwendet werden, sondern ich beschäftige mich nur mit Zeichenfolgen.


6
Viele Antworten berücksichtigen nicht den zweiten Teil der Frage. Wenn Get-Item, Get-ChildItem oder deren Aliase ls, dir, gi, gci verwendet werden, muss die Datei aus der getesteten Zeichenfolge vorhanden sein . Wenn wir eine Reihe von Zeichenfolgen überprüfen und nicht durch ein Verzeichnis iterieren , muss davon ausgegangen werden, dass diese Dateien nicht auf dem Computer vorhanden sein müssen, auf dem dieses Skript ausgeführt wird.
Papo

Antworten:


109

Dafür gibt es eine praktische .NET-Methode:

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

93

Viel einfacher als ich dachte, um das Problem der Anzeige des vollständigen Pfads, Verzeichnisses, Dateinamens oder der Dateierweiterung zu lösen.

$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

andere Formen:

$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
Es wäre schön, wenn Sie neben jedem Beispiel im oberen Codeausschnitt genau zeigen würden, welcher Text zurückgegeben werden würde.
tödlicher Hund

Beispiel, wo ich den CSR-Dateinamen nicht kenne, aber ich weiß, dass eine Datei existiert: $csr = Get-ChildItem -Path "$($domain.FullName)/*.csr"dannWrite-Host "fileName: $($csr.Basename)"
Scott Pelak

46

Inspiriert von einer Antwort von @ walid2mi:

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

Bitte beachten Sie: Dies funktioniert nur, wenn die angegebene Datei wirklich vorhanden ist .


1
Dies ist der einfachste Weg, um den Dateinamen für eine einzelne Datei zu erhalten.
Marisks

5
Dies setzt voraus, dass die Datei vorhanden ist. Das Entfernen einer Erweiterung aus einem Dateinamen sollte nicht davon abhängen. Was ist, wenn Sie eine Datei basierend auf einem Dateinamen erstellen, in dem die Datei nicht vorhanden ist? Der Pfad ist eine Zeichenfolge und sollte als Zeichenfolge behandelt werden, nicht als vorhandene Datei.
Antony Booth

29

oder

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

oder

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

9
Das zweite Beispiel funktioniert nicht so gut mit so etwas wie "C: \ Downloads \ ReSharperSetup.7.0.97.60.msi" .split ('\.') [- 2]
Keith Hill

24

Sie können die Eigenschaft basename verwenden

PS II> ls *.ps1 | select basename

7
Das OP sagt: Ich iteriere nicht wirklich durch ein Verzeichnis.
CB.

1
Sehr nützlich für mich!
Iheartcsharp

5

@ Keith ,

hier eine andere Option:

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

Bei jeder beliebigen Pfadzeichenfolge ergeben verschiedene statische Methoden für das System.IO.Path-Objekt die folgenden Ergebnisse.

strTestPath = C: \ Benutzer \ DAG \ Dokumente \ Artikel_2018 \ NTFS_File_Times_in_CMD \ PathStringInfo.ps1
GetDirectoryName = C: \ Benutzer \ DAG \ Dokumente \ Artikel_2018 \ NTFS_File_Times_in_CMD
GetFileName = PathStringInfo.ps1
GetExtension = .ps1
GetFileNameWithoutExtension = PathStringInfo

Es folgt der Code, der die obige Ausgabe generiert hat.

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

Das Schreiben und Testen des Skripts, das das oben Genannte generiert hat, hat einige Macken darüber aufgedeckt, wie sich PowerShell von C #, C, C ++, der Windows NT-Befehlsskriptsprache und fast allem anderen unterscheidet, mit dem ich Erfahrung habe.


3

Ab PowerShell 6 erhalten Sie den Dateinamen ohne Erweiterung wie folgt:

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

Dies ist in Powershell 6 korrekt. Es gibt keine LeafBase in Moor Standard 5.1
Finlaybob

1
Danke für die Info, ich habe die Antwort entsprechend aktualisiert. Was ist Moor ?
René Nyffenegger

2
Entschuldigung :) wo ich aus (UK) komme, ist "Bog Standard" ein Slangbegriff für etwas ganz Gewöhnliches, eine "Vanille" -Version.
Finlaybob

2

Dieses Skript sucht in einem Ordner und in Unterordnern und benennt Dateien um, indem deren Erweiterung entfernt wird

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

    Foreach-Object {

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

    }

2

Um die Antwort von René Nyffenegger zu erweitern, verwenden wir für diejenigen, die keinen Zugriff auf PowerShell Version 6.x haben, den geteilten Pfad, der nicht auf die Existenz von Dateien testet:

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

Dies gibt " myfile.txt " zurück. Wenn wir wissen, dass der Dateiname keine Punkte enthält, können wir die Zeichenfolge teilen und den ersten Teil übernehmen:

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

oder

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

Dies gibt " myfile " zurück. Wenn der Dateiname aus Sicherheitsgründen Punkte enthalten könnte, könnten wir Folgendes verwenden:

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

Dies gibt " myfile.txt.config " zurück. Hier bevorzuge ich die Verwendung von Substring () anstelle von Replace (), da die Erweiterung, der ein Punkt vorangestellt ist, auch Teil des Namens sein kann, wie in meinem Beispiel. Bei Verwendung von Teilzeichenfolge geben wir den Dateinamen ohne die gewünschte Erweiterung zurück.


1
Vielen Dank für diese Antwort, sie ist sehr vollständig und hat mir geholfen
Sam

1

Hier ist eine ohne Klammern

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

1

Dies kann durch mehrmaliges Teilen der Zeichenfolge erfolgen.

#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

Hier ist der Code ohne Kommentare:

$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
Warum so schwer?
Jaroslav Štreit

2
Funktioniert nicht, wenn der Dateiname mehr als einen Punkt enthält, z. B. MyApp.exe.config
Joe
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.