Подтвердить что ты не робот

Как получить эквивалент dirname() в пакетном файле?

Я хочу получить родительский каталог файла из файла .bat. Поэтому, если переменная установлена ​​в "C:\MyDir\MyFile.txt", я бы хотел получить "C:\MyDir". Другими словами, эквивалент функциональности dirname() в типичной среде UNIX. Возможно ли это?

4b9b3361

Ответ 1

for %%F in (%filename%) do set dirname=%%~dpF

Это установит %dirname% в дисковод и каталог имени файла, хранящегося в %filename%.

Осторожно с именами файлов, содержащих пробелы. Либо они должны быть установлены с окружающими кавычками:

set filename="C:\MyDir\MyFile with space.txt"

или вам нужно поставить кавычки вокруг аргумента в цикле for:

for %%F in ("%filename%") do set dirname=%%~dpF

Любой из этих методов будет работать, и в то же время не будет: -)

Ответ 2

Если по какой-либо причине вы не можете использовать FOR (без командных расширений и т.д.), вы можете уйти с помощью.. \hack:

set file=c:\dir\file.txt
set dir=%file%\..\

Ответ 3

Проблема с циклом for заключается в том, что она оставляет конечный символ\в конце строки. Это вызывает проблемы, если вы хотите получить имя dirname несколько раз. Возможно, вам нужно получить имя каталога, являющегося прародителем каталога, содержащего этот файл, а не только родительский каталог. Просто используя технику for loop второй раз удалит\и не получит каталог grandparent.

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

set filename=c:\1\2\3\t.txt
for %%F in ("%filename%") do set dirname=%%~dpF
for %%F in ("%dirname%") do set dirname=%%~dpF

Это установит dirname в "c:\1\2\3", а не "c:\1\2".

Следующая функция решает эту проблему, также удаляя конечную \.

:dirname file varName
    setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
    SET _dir=%~dp1
    SET _dir=%_dir:~0,-1%
    endlocal & set %2=%_dir%
GOTO :EOF

Он вызывается следующим образом.

set filename=c:\1\2\3\t.txt
call :dirname "%filename%" _dirname
call :dirname "%_dirname%" _dirname