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.

larryq
quelle
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
Keith Hill
quelle
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)
Leonardo
quelle
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 .

CodeFox
quelle
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]
walid2mi
quelle
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
walid2mi
quelle
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]
walid2mi
quelle
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.

David A. Gray
quelle
3

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

split-path c:\temp\myfile.txt -leafBase
René Nyffenegger
quelle
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

    }
user12386990
quelle
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.

Papa Ccompis
quelle
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
Steven Penny
quelle
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
OneOfThePetes
quelle
1
Warum so schwer?
Jaroslav Štreit
2
Funktioniert nicht, wenn der Dateiname mehr als einen Punkt enthält, z. B. MyApp.exe.config
Joe