Was ist der beste Weg, um einen Teilstring in einer Batch-Datei zu erstellen?

192

Ich möchte den Namen der aktuell ausgeführten Batchdatei ohne die Dateierweiterung erhalten.

Dank dieses Links habe ich den Dateinamen mit der Erweiterung ... aber wie kann man einen Teilstring in einer Batchdatei am besten erstellen?

Oder gibt es eine andere Möglichkeit, den Dateinamen ohne die Erweiterung zu erhalten?

In diesem Szenario können 3 Buchstabenerweiterungen angenommen werden.

JosephStyons
quelle

Antworten:

395

Nun, um nur den Dateinamen Ihres Stapels zu erhalten, ist es am einfachsten, ihn einfach zu verwenden %~n0.

@echo %~n0

gibt den Namen (ohne die Erweiterung) der aktuell ausgeführten Batchdatei aus (sofern er nicht in einer von aufgerufenen Unterroutine ausgeführt wird call). Die vollständige Liste solcher „speziellen“ Ersetzungen für Pfadnamen finden Sie help forganz am Ende der Hilfe:

Darüber hinaus wurde die Substitution von FOR-Variablenreferenzen verbessert. Sie können jetzt die folgende optionale Syntax verwenden:

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

Die Modifikatoren können kombiniert werden, um zusammengesetzte Ergebnisse zu erhalten:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only

Um Ihre Frage jedoch genau zu beantworten: Teilzeichenfolgen werden mit der :~start,lengthNotation erstellt:

%var:~10,5%

extrahiert 5 Zeichen von Position 10 in der Umgebungsvariablen %var%.

HINWEIS: Der Index der Zeichenfolgen basiert auf Null, sodass sich das erste Zeichen an Position 0, das zweite an 1 usw. befindet.

Um Teilargumentations Variablen wie zu bekommen %0, %1etc. müssen Sie sie eine normale Umgebungsvariable zuweisen Verwendung setzuerst:

:: Does not work:
@echo %1:~10,5

:: Assign argument to local variable first:
set var=%1
@echo %var:~10,5%

Die Syntax ist noch leistungsfähiger:

  • %var:~-7% extrahiert die letzten 7 Zeichen aus %var%
  • %var:~0,-4%würde alle Zeichen außer den letzten vier extrahieren, wodurch Sie auch die Dateierweiterung entfernen würden (unter der Annahme von drei Zeichen nach dem Punkt [ .]).

Siehe help setDetails zu dieser Syntax.

Joey
quelle
31
Die Teilzeichenfolgenextraktion funktioniert auch nicht mit FOR-Schleifenvariablen, daher müssen Sie wie folgt vorgehen (\ r \ n im Code bedeutet Zeilenumbrüche, da SO Zeilenumbrüche in Kommentaren nicht setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
zulässt
@ Fr0sT warum musst du das für FORSchleifen machen?
Bob
4
@ Adrian warum nicht? FORist eine Eckpfeilerkonstruktion in Batch-Dateien, die eine große Anzahl verschiedener Aufgaben ausführen. Übrigens gibt es noch eine Möglichkeit, die Aufgabe mit einem Unterprogramm zu bewältigen, dhfor /f %%s in ('set') do call :DoSmth "%%s" \r\n ... \r\n :DoSmth \r\n set var=%1 \r\n echo %var:~1,3%
Fr0sT
1
Unter Windows Server 12 R2 sieht% date% wie am 21.05.18 aus (IT-Kultur). Die richtige Zeichenfolge lautet: %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01
@ Phate01, nicht verwenden %date%, um ein Datum in einem bestimmten Format zu erstellen . Das Format ist spezifisch für die Kultur des Benutzers und kann sich ändern. Verwenden Sie stattdessen WMI, um Datum und Uhrzeit in einem nützlichen Format abzurufen, das nicht von den Einstellungen des Benutzers abhängt. Ich bin mir auch nicht sicher, was dieser Kommentar hier macht, da es bei dieser Frage nicht um Datum oder Uhrzeit ging.
Joey
38

Oben schön erklärt!

Für alle, die wie ich leiden müssen, damit dies in einem lokalisierten Windows funktioniert (meins ist XP auf Slowakisch), können Sie versuchen, das %durch ein zu ersetzen!

So:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!
BrandonSk
quelle
27
Beachten Sie, dass dies nur nach dem setlocal ENABLEDELAYEDEXPANSIONBefehl
funktioniert
13

Als zusätzliche Info zu Joeys Antwort, die in der Hilfe von set /?nor nicht beschrieben wird for /?.

%~0Erweitert sich auf den Namen des eigenen Stapels, genau so, wie er eingegeben wurde.
Wenn Sie also Ihren Stapel starten, wird er als erweitert

%~0   - mYbAtCh
%~n0  - mybatch
%~nx0 - mybatch.bat

Es gibt jedoch eine Ausnahme: Das Erweitern einer Unterroutine kann fehlschlagen

echo main- %~0
call :myFunction
exit /b

:myFunction
echo func - %~0
echo func - %~n0
exit /b

Dies führt zu

main - myBatch
Func - :myFunction
func - mybatch

In einer Funktion wird %~0immer der Name der Funktion erweitert, nicht der Batchdatei.
Wenn Sie jedoch mindestens einen Modifikator verwenden, wird der Dateiname erneut angezeigt!

jeb
quelle