Каков наилучший способ сделать подстроку в командном файле?

192

Я хочу получить имя запущенного в данный момент пакетного файла без расширения файла.

Благодаря этой ссылке у меня есть имя файла с расширением ... но как лучше всего сделать подстроку в командном файле?

Или есть другой способ получить имя файла без расширения?

В этом сценарии можно предположить 3-буквенное расширение.

JosephStyons
источник

Ответы:

398

Ну, для получения имени файла вашей партии самый простой способ - просто использовать %~n0.

@echo %~n0

выведет имя (без расширения) запущенного в данный момент пакетного файла (если не выполнено в подпрограмме, вызываемой call). Полный список таких «специальных» подстановок имен путей можно найти help forв самом конце справки:

Кроме того, была улучшена замена ссылок на переменные FOR. Теперь вы можете использовать следующий необязательный синтаксис:

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

Модификаторы могут быть объединены для получения составных результатов:

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

Чтобы точно ответить на ваш вопрос, однако: Подстроки делаются с использованием :~start,lengthзаписи:

%var:~10,5%

извлечет 5 символов из позиции 10 в переменной окружения %var%.

ПРИМЕЧАНИЕ . Индекс строк начинается с нуля, поэтому первый символ находится в позиции 0, второй в 1 и т. Д.

Чтобы получить подстроки переменных аргументов, таких как %0, %1и т. Д., Вы должны назначить их нормальной переменной среды, используя setfirst:

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

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

Синтаксис еще более мощный:

  • %var:~-7% извлекает последние 7 символов из %var%
  • %var:~0,-4%извлечет все символы, кроме последних четырех, что также избавит вас от расширения файла (при условии трех символов после точки [ .]).

Смотрите help setподробности об этом синтаксисе.

детеныш
источник
31
Извлечение подстроки также не работает с переменными цикла FOR, поэтому вам придется сделать следующее (\ r \ n в коде означает разрывы строк, потому что кажется, что SO не допускает разрывы строк в комментариях):setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
Fr0sT
@ Fr0sT, почему ты должен делать это для FORциклов?
Боб
4
@ Адриан, почему нет? FORявляется краеугольным камнем в пакетных файлах, выполняющих довольно большое количество различных задач. Кстати, есть еще один способ справиться с задачей, используя подпрограмму, а именно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
используя windows server 12 R2,% date% выглядит как 21/05/18 (ИТ-культура); правильная строка: %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01
@ Phate01, не используйте %date%для построения даты в определенном формате. Формат зависит от культуры пользователя и может измениться. Вместо этого используйте WMI, чтобы получить дату и время в удобном формате, который не зависит от настроек пользователя. Также я не уверен, что этот комментарий делает здесь, так как этот вопрос не был о дате или времени.
Джои
38

Красиво объяснил выше!

Для всех тех , кто может пострадать , как мне получить эту работу в локализованной Windows (шахта XP в словацком), вы можете попытаться заменить %с!

Так:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!
BrandonSk
источник
27
Обратите внимание, что это будет работать только после setlocal ENABLEDELAYEDEXPANSIONкоманды
Fr0sT
13

В качестве дополнительной информации к ответу Джои, которая не описана в справке set /?ни for /?.

%~0расширяется до имени собственной партии, в точности так, как она была напечатана.
Так что, если вы начнете свою партию, она будет расширена как

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

Но есть одно исключение, расширение подпрограммы может потерпеть неудачу

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

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

Это приводит к

main - myBatch
Func - :myFunction
func - mybatch

В функции %~0всегда раскрывается имя функции, а не командный файл.
Но если вы используете хотя бы один модификатор, он снова покажет имя файла!

Джеб
источник