Как получить путь к папке из пути к файлу с CMD


151

Мне нужен путь к папке, содержащей файл cmd. С% 0 я могу получить имя файла. Но как получить имя папки?

c: \ temp \ test.cmd >> test.cmd

PS Моя текущая директория! = Папка скрипта.

Ответы:


310

Для имени папки и диска вы можете использовать:

echo %~dp0

Вы можете получить гораздо больше информации, используя различные модификаторы:

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

The modifiers can be combined to get compound results:
%~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

Это копия вставки из "для /?" Команда в командной строке. Надеюсь, поможет.

Связанный

Топ 10 советов по DOS Batch (Да, DOS Batch ...) показывает batchparams.bat (ссылка на источник в виде сущности):

C:\Temp>batchparams.bat c:\windows\notepad.exe
%~1     =      c:\windows\notepad.exe
%~f1     =      c:\WINDOWS\NOTEPAD.EXE
%~d1     =      c:
%~p1     =      \WINDOWS\
%~n1     =      NOTEPAD
%~x1     =      .EXE
%~s1     =      c:\WINDOWS\NOTEPAD.EXE
%~a1     =      --a------
%~t1     =      08/25/2005 01:50 AM
%~z1     =      17920
%~$PATHATH:1     =
%~dp1     =      c:\WINDOWS\
%~nx1     =      NOTEPAD.EXE
%~dp$PATH:1     =      c:\WINDOWS\
%~ftza1     =      --a------ 08/25/2005 01:50 AM 17920 c:\WINDOWS\NOTEPAD.EXE

Прохладно. Нужно ли мне конкретный счет, чтобы изменить чужой пост вики?
Вади М.

@Wadih M .: Обычно полезная ссылка stackoverflow.com/questions/18557/…
jfs

@Wadih M .: В частности stackoverflow.com/questions/130654/…
jfs

@Wadih M .: Из приведенной выше ссылки: «+750, чтобы редактировать сообщения сообщества, редактируемые вики»
jfs

Поэтому, если вы хотите, чтобы сценарий cmd устанавливал рабочий каталог в местоположение сценария: cd /d "%~dp0"(из stackoverflow.com/questions/4451668 )
Nigel Touch

52

Принятый ответ полезен, но не сразу очевидно, как извлечь имя файла из пути, если вы НЕ используете переданные значения. Я смог решить это из этой темы, но в случае, если другим не так повезло, вот как это делается:

@echo off
setlocal enabledelayedexpansion enableextensions

set myPath=C:\Somewhere\Somewhere\SomeFile.txt
call :file_name_from_path result !myPath!
echo %result%
goto :eof

:file_name_from_path <resultVar> <pathVar>
(
    set "%~1=%~nx2"
    exit /b
)

:eof
endlocal

Теперь :file_name_from_pathфункция может использоваться где угодно для получения значения, а не только для переданных в аргументах. Это может быть чрезвычайно полезно, если аргументы могут быть переданы в файл в неопределенном порядке или путь вообще не передан в файл.


вау, это потрясающе! Так что функции поддержки пакетных файлов Windows внутри одного и того же файла, как полезно! С каких это пор это было возможно?
Лука

2
Мне нравится, что вы можете передавать переменные как по ссылке (как есть), так и по значению (в окружении "!"). Ладно, у вас, вероятно, нет «локальных» переменных и стека вызовов ... но, эй: в конце концов, это сценарий cmd, в любом случае это большой шаг вперед;) Согласен, разделение содержимого внутри одного файла гораздо удобнее чем разделить его на несколько файлов :)
Лука

1
Я думаю, что "goto: eof" должно быть "goto eof" ... без двоеточия ... как это ломалось для меня.
Худайри

2
Смотрите также: ss64.com/nt/syntax-args.html - используйте только %~dp1для диска и пути.
Андрей

2
@AKhudairy верен: ss64.com/nt/goto.html С двоеточием goto пропускает эндокалорий (и все, что вы потом добавляете, как пауза). Также вам нужно добавить "s, !myPath!если в вашем пути есть пробелы (или кавычки должны быть частью myPath)
Рик

8

Чтобы назначить их переменным, не добавляйте пробелы перед или после знака равенства:

set filepath=%~dp1
set filename=%~nx1

Тогда у вас не должно быть проблем.


5

В случае, если кто-то хочет альтернативный метод ...

Если это последний подкаталог в пути, вы можете использовать этот однострочный:

cd "c:\directory\subdirectory\filename.exe\..\.." && dir /ad /b /s

Это вернет следующее:

c:\directory\subdirectory

.... возвращается к предыдущему каталогу. / ad показывает только каталоги / b - список в чистом формате / s включает все подкаталоги. Это используется для получения полного пути к каталогу для печати.


Вероятно, он работает с текущим каталогом, а не с каталогом, в котором находится файл скрипта.
Майк Чалий

4

У меня была та же проблема в моем цикле, когда я хотел извлечь ZIP-файлы в том же каталоге, а затем удалить ZIP-файл. Проблема заключалась в том, что 7z требует выходной папки, поэтому мне пришлось получить путь к папке каждого файла. Вот мое решение:

FOR /F "usebackq tokens=1" %%i IN (`DIR /S/B *.zip` ) DO (
  7z.exe x %%i -aoa -o%%i\..
) 

%% i был полным путем к имени файла, а% ii \ .. просто возвращает родительскую папку.

Надеюсь, поможет.


Быстро и грязно. Мне нравится это! Никогда не думал, что вы расширите путь к файлу с помощью «\ ..» и в итоге получите родительскую папку.
Оливер Р.

Это работало для меня на Win10: FOR / R "C: \ sourceDir"% I IN (* .gz) DO C: \ 7-Zip64 \ 7z.exe x "% I" -aou -o% I \ .. \
b3wii

Да! Это позволяет обойти проблему, заключающуюся в том, что% ~ dp1 (и т. Д.)
Работают


0

Это было сделано вместе с некоторым отредактированным примером cmd

@Echo off

Echo ********************************************************
Echo *  ZIP Folder Backup using 7Zip                        *
Echo *  Usage: Source Folder, Destination Drive Letter      *
Echo *  Source Folder will be Zipped to Destination\Backups *
Echo ********************************************************
Echo off

set year=%date:~-4,4%
set month=%date:~-10,2%
set day=%date:~-7,2%
set hour=%time:~-11,2%
set hour=%hour: =0%
set min=%time:~-8,2%

SET /P src=Source Folder to Backup: 
SET source=%src%\*
call :file_name_from_path nam %src%
SET /P destination=Backup Drive Letter:
set zipfilename=%nam%.%year%.%month%.%day%.%hour%%min%.zip
set dest="%destination%:\Backups\%zipfilename%"


set AppExePath="%ProgramFiles(x86)%\7-Zip\7z.exe"
if not exist %AppExePath% set AppExePath="%ProgramFiles%\7-Zip\7z.exe"

if not exist %AppExePath% goto notInstalled

echo Backing up %source% to %dest%

%AppExePath% a -r -tzip %dest% %source%

echo %source% backed up to %dest% is complete!

TIMEOUT 5

exit;

:file_name_from_path <resultVar> <pathVar>
(
    set "%~1=%~nx2"
    exit /b
)


:notInstalled

echo Can not find 7-Zip, please install it from:
echo  http://7-zip.org/

:end
PAUSE
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.