Jaki jest najlepszy sposób na wykonanie podciągu w pliku wsadowym?

192

Chcę uzyskać nazwę aktualnie uruchomionego pliku wsadowego bez rozszerzenia pliku.

Dzięki temu linkowi mam nazwę pliku z rozszerzeniem ... ale jaki jest najlepszy sposób na utworzenie podciągu w pliku wsadowym?

Czy istnieje inny sposób na uzyskanie nazwy pliku bez rozszerzenia?

W tym scenariuszu można bezpiecznie założyć 3-literowe przedłużenia.

JosephStyons
źródło

Odpowiedzi:

398

Cóż, dla uzyskania nazwy pliku partii najłatwiej byłoby po prostu użyć %~n0.

@echo %~n0

wyświetli nazwę (bez rozszerzenia) aktualnie uruchomionego pliku wsadowego (chyba że zostanie wykonany w podprogramie wywoływanym przez call). Kompletną listę takich „specjalnych” podstawień dla nazw ścieżek można znaleźć help forna końcu pomocy:

Ponadto ulepszono podstawianie odwołań do zmiennych FOR. Możesz teraz użyć następującej opcjonalnej składni:

%~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

Modyfikatory można łączyć, aby uzyskać złożone wyniki:

%~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

Aby jednak precyzyjnie odpowiedzieć na twoje pytanie: podłańcuchy są wykonywane za pomocą :~start,lengthnotacji:

%var:~10,5%

wyodrębni 5 znaków z pozycji 10 w zmiennej środowiskowej %var%.

UWAGA: Indeks ciągów jest oparty na zerach, więc pierwszy znak znajduje się w pozycji 0, drugi w pozycji 1 itd.

Aby uzyskać podciągi zmiennych argumentów, takich jak %0, %1itp., Musisz najpierw przypisać je do normalnej zmiennej środowiskowej set:

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

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

Składnia jest jeszcze bardziej rozbudowana:

  • %var:~-7% wyodrębnia 7 ostatnich znaków %var%
  • %var:~0,-4%wyodrębni wszystkie znaki oprócz czterech ostatnich, co również pozbawi cię rozszerzenia pliku (przyjmując trzy znaki po kropce [ .]).

Zobacz help setszczegóły dotyczące tej składni.

Joey
źródło
31
Wyodrębnianie podciągów również nie działa ze zmiennymi pętli FOR, więc będziesz musiał wykonać następujące czynności (\ r \ n w kodzie oznacza setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
podział
@ Fr0sT dlaczego musisz to zrobić dla FORpętli?
Bob
4
@Adrian, dlaczego nie? FORjest kamieniem węgielnym w plikach wsadowych, wykonujących całkiem dużą liczbę różnych zadań. Przy okazji istnieje jeszcze jeden sposób poradzenia sobie z zadaniem za pomocą podprogramu, tj.for /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
używając Windows Server 12 R2,% date% wygląda jak 21/05/18 (kultura IT); prawy ciąg to: %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01
@ Phate01, nie używaj %date%do konstruowania daty w określonym formacie. Format jest specyficzny dla kultury użytkownika i może ulec zmianie. Zamiast tego użyj WMI, aby uzyskać datę i godzinę w przydatnym formacie, który nie zależy od ustawień użytkownika. Nie jestem też pewien, co robi ten komentarz, ponieważ to pytanie nie dotyczyło daty ani godziny.
Joey
38

Ładnie wyjaśnione powyżej!

Dla wszystkich tych, którzy mogą cierpieć tak jak ja, aby dostać tę pracę w miejscowej kopalni jest Windows (XP w języku słowackim), można spróbować zastąpić %z!

Więc:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!
BrandonSk
źródło
27
Uwaga: zadziała to dopiero po wydaniu setlocal ENABLEDELAYEDEXPANSIONpolecenia
Fr0sT
13

Jako dodatkową informację do odpowiedzi Joeya, która nie jest opisana w pomocy set /?nor for /?.

%~0rozwija się do nazwy własnej partii, dokładnie tak, jak została wpisana.
Więc jeśli rozpoczniesz swoją partię, zostanie ona rozszerzona jako

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

Ale jest jeden wyjątek: rozszerzenie podprogramu może się nie powieść

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

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

To prowadzi do

main - myBatch
Func - :myFunction
func - mybatch

W funkcji %~0zawsze rozwija się do nazwy funkcji, a nie pliku wsadowego.
Ale jeśli użyjesz co najmniej jednego modyfikatora, ponownie wyświetli nazwę pliku!

jeb
źródło