Есть ли способ в пакетном скрипте Windows вернуть абсолютный путь из значения, содержащего имя файла и / или относительный путь?
Дано:
"..\"
"..\somefile.txt"
Мне нужен абсолютный путь относительно командного файла.
Пример:
- «somefile.txt» находится в «C: \ Foo \»
- "test.bat" находится в "C: \ Foo \ Bar".
- Пользователь открывает окно команд в «C: \ Foo» и вызывает
Bar\test.bat ..\somefile.txt
- В командном файле "C: \ Foo \ somefile.txt" будет получен из
%1
windows
batch-file
relative-path
absolute-path
Натан Тейлор
источник
источник
realpath
для надежной нормализации пути.SET FilePath=%CD%\%1
чтобы он мог быть похожимC:\Foo\Bar\..\..\some\other\dir\file.txt
. Программы, кажется, понимают такой сложный путь.Ответы:
В пакетных файлах, как и в стандартных программах на C, аргумент 0 содержит путь к текущему исполняемому сценарию. Вы можете использовать,
%~dp0
чтобы получить только часть пути 0-го аргумента (который является текущим сценарием) - этот путь всегда является полностью определенным путем.Вы также можете получить полный путь к первому аргументу с помощью
%~f1
, но это дает путь в соответствии с текущим рабочим каталогом, что явно не то, что вам нужно.Лично я часто использую
%~dp0%~1
идиому в моем пакетном файле, которая интерпретирует первый аргумент относительно пути исполняемого пакета. Однако у него есть недостаток: он с треском проваливается, если первый аргумент полностью квалифицирован.Если вам нужно поддерживать как относительные, так и абсолютные пути, вы можете воспользоваться решением Фредерика Менеза : временно изменить текущий рабочий каталог.
Вот пример, который продемонстрирует каждый из этих методов:
Если вы сохраните его как c: \ temp \ example.bat и запустите его из c: \ Users \ Public как
c: \ Users \ Public> \ temp \ example.bat .. \ windows
... вы увидите следующий вывод:
документацию для набора модификаторов, разрешенных для аргумента пакета, можно найти здесь: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/call
источник
%0
и%1
аналогичным образом:%~dpnx0
для полного пути + имя самого пакетного файла,%~dpnx1
для полного пути + имя его первого аргумента [если это вообще имя файла]. (Но как же вы назвали бы файл на другом диске, если бы в любом случае неd:\foo\..\bar\xyz.txt
все еще можно нормализовать. Я рекомендую использовать этот подход с ответом @ axel-heider ниже (используя пакетную подпрограмму - тогда вы можете сделать это для любой переменной, а не только для пронумерованной переменной).Сегодня утром я столкнулся с аналогичной потребностью: как преобразовать относительный путь в абсолютный путь внутри командного сценария Windows.
Следующие сделали свое дело:
источник
pushd .
предотвращает эту проблему.Большинство из этих ответов кажутся сумасшедшими из-за сложных и супер глючных, вот мой - он работает с любой переменной среды, нет
%CD%
илиPUSHD
/POPD
илиfor /f
ерунда - просто старые пакетные функции - Каталог и файл даже не должны существовать.источник
%~f1
просто коротко%~dpfn1
- так что не стесняйтесь использовать%~f1
вместо этого. 🙂 - в длинном формате~
означает удалить кавычки,d
означает диск,p
означает путь,n
само по себе будет имя файла без расширения, ноfn
означает имя файла с расширением.1
означает первый аргумент. - (Я полагаю, этот формат предшествует Windows 7.)Не имея другого пакетного файла для передачи аргументов (и использования операторов аргументов), вы можете использовать
FOR /F
:где
i
in%%~fi
является переменной, определенной в/F %%i
. например. если вы изменили это,/F %%a
то последняя часть будет%%~fa
.Чтобы сделать то же самое прямо в командной строке (а не в командном файле), заменить
%%
на%
...источник
cd
команда не обязательно меняет%CD%
переменную среды (если, например, вы находитесь на дискеD:
и ваш целевой путьC:
cd /D D:\on.other.drive
FOR /F %%i IN ("..\relativePath") DO echo absolute path: %%~fi
потерпит неудачу, если..\relativePath
содержит пробелыfor /?
предлагает использовать заглавные буквы для имен переменных, чтобы избежать путаницы с параметрами подстановки/F
не будет работать с несуществующими путями и разрешает символы подстановки. Если вы хотите этого, отлично, но если вы хотите функциональность/F
, то вам просто нужно использоватьtokens
ключевое слово:FOR /F "tokens=*" %%I IN ("..\relative Path\*") DO echo absolute path: %%~fI
Это поможет заполнить пробелы в ответе Эдриана Плиссона (который должен быть одобрен, как только он его отредактирует ;-):
Можно справиться
%0
и%1
аналогично:%~dpnx0
для полностью определенного диска + путь + имя + расширение самого пакетного файла%~f0
также достаточно;%~dpnx1
для полностью определенного диска + путь + имя + расширение его первого аргумента [если это вообще имя файла],%~f1
также достаточно;%~f1
будет работать независимо от того, как вы указали свой первый аргумент: с относительными путями или с абсолютными путями (если вы не укажете расширение файла при именовании%1
, оно не будет добавлено, даже если вы используете%~dpnx1
- однако.Но как на самом деле вы бы назвали файл на другом диске в любом случае, если бы не указали эту полную информацию о пути в командной строке?
Однако
%~p0
,%~n0
,%~nx0
и%~x0
может пригодиться, вы должны быть заинтересованы в пути (без Буква_диска), имя файла (без расширения), полное имя файла с расширением или расширение имени файла только. Но учтите, что while%~p1
и%~n1
будет работать, чтобы выяснить путь или имя первого аргумента,%~nx1
и%~x1
не будет добавлять + показывать расширение, если вы уже не использовали его в командной строке.источник
%~dpnx1
том, что он дает полный путь к аргументу относительно текущего каталога , в то время как OP хочет путь относительно каталога, в котором находится пакетный файл .%~dpnx1
дает полный путь 1-го аргумента. Относительно не относительно , и не относительно текущего каталога. Этоd
для диска,p
для пути,n
для суффикса без имени файла,x
для суффикса,1
для первого аргумента. - И вопрос Натана был: «Есть ли способ вернуть абсолютный путь из значения, содержащего имя файла и / или относительный путь?»Вы также можете использовать пакетные функции для этого:
источник
Небольшое улучшение отличного решения BrainSlugs83 . Обобщается, чтобы разрешить именование выходной переменной среды в вызове.
Если запустить из
C:\project
вывода:источник
Я не видел много решений этой проблемы. Некоторые решения используют обход каталога с использованием CD, а другие используют пакетные функции. Мои личные предпочтения были для пакетных функций и, в частности, для функции MakeAbsolute, предоставленной DosTips.
Функция имеет некоторые реальные преимущества, в первую очередь, в том, что она не меняет ваш текущий рабочий каталог, и во-вторых, что оцениваемые пути даже не должны существовать. Вы можете найти некоторые полезные советы о том , как использовать функцию здесь тоже.
Вот пример сценария и его результаты:
И вывод:
Надеюсь, это поможет ... Это, безусловно, помогло мне :) PS Еще раз спасибо DosTips! Ты жжешь!
источник
Вы можете просто объединить их.
это выглядит странно с \ .. \ в середине вашего пути, но это работает. Не нужно ничего сумасшедшего делать :)
источник
echo %~dp0..\SomeFile.txt
В вашем примере из Bar \ test.bat DIR / B / S .. \ somefile.txt вернет полный путь.
источник
PowerShell довольно распространен в наши дни, поэтому я часто использую его для быстрого вызова C #, поскольку в нем есть функции практически для всего:
Это немного медленно, но полученную функциональность сложно превзойти, если не прибегнуть к реальному языку сценариев.
источник
Решение Stijn работает с подпапками
C:\Program Files (86)\
,источник
Файлы Посмотреть все остальные ответы
Справочники
С
..
быть вашим относительный путь, и если вы находитесь в данный моментD:\Projects\EditorProject
:cd .. & cd & cd EditorProject
(относительный путь)возвращает абсолютный путь, например
D:\Projects
источник
источник