Как получить относительный путь из пакетного файла Windows с помощью эха?

Как получить относительные каталоги / частичные пути для отображения в виде эхо-вывода из файла Windows .bat?

Как отделить имя файла от полного пути в партия?

Говорит обо всем, кроме.

Я нашел буквы дисков, имена файлов, расширения, сокращенные (8.3) имена и полные пути, но не относительные пути.

Я запускаю рекурсивный цикл FOR /R; который пересекает подкаталоги. Я хотел бы что-то - в этом нет двадцати символов бесполезной информации о пути - что говорит мне, в каком каталоге находится каждый дублирующийся файл ... без жесткого кодирования файла .bat для размещения в определенном каталоге / пути?

Может быть, решением было бы измерить длину пути сценария и отрезать его от начала полного пути? Но я не знаю, как этим манипулировать.

Скрипт может находиться во многих местах:

F:\a.bat<BR>
F:\Dir1\fileA.txt<BR>
F:\Dir20\fileA.txt

C:\Users\Longusername\Desktop\Container\a.bat<BR>
C:\Users\Longusername\Desktop\Container\Dir1\fileA<BR>
C:\Users\Longusername\Desktop\Container\Dir20\fileA

И прямо сейчас у меня есть только варианты вывода (%%~nxG):

fileA.txt
fileA.txt

Что не говорит мне, в каком каталоге находится каждый файл... или (%%~pnxG)

\Users\Longusername\Desktop\Container\Dir1\fileA.txt
\Users\Longusername\Desktop\Container\Dir20\fileA.txt

Что я хотел бы, из любого места:

\Dir1\fileA.txt
\Dir20\fileA.txt

Может отсутствовать начальный \, но это незначительно. Допустимы и другие параметры, кроме эха, если они будут работать на большинстве оконных машин. Однако они могут привести к большему количеству вопросов - как я выяснил другие мои части с эхом.


person user3082    schedule 08.09.2019    source источник


Ответы (3)


довольно просто, если подумать: просто удалите текущий путь к каталогу (%cd%):

@echo off 
setlocal enabledelayedexpansion
for /r %%a in (*.txt) do (
  set "x=%%a"
  echo with \:    !x:%cd%\=\!
  echo without \: !x:%cd%\=!
)

Кстати: \folder\file всегда относится к корню диска (x:\folder\file), так что это не совсем относительный путь.

person Stephan    schedule 08.09.2019
comment
Идеально. Я не нашел текущий каталог. Должен был выглядеть серьезнее. - person user3082; 08.09.2019
comment
Это всегда очевидно, это трудно увидеть... ;) - person Stephan; 08.09.2019

Это похоже на уже принятый ответ, но с отложенным расширением, включенным только там, где это необходимо. Это должно правильно выводить имена файлов, содержащие символы !.

@Echo Off
SetLocal DisableDelayedExpansion

Set "TopLevel=C:\Users\LongUserName"

For /R "%TopLevel%" %%A In ("*.txt") Do (
    Set "_=%%A"
    SetLocal EnableDelayedExpansion
    Echo=!_:*%TopLevel%=!
    EndLocal
)

Pause

Вы также можете использовать Set "TopLevel=%~dp0", (каталог запущенного скрипта) или Set "TopLevel=%~dp0..", (родительский каталог запущенного скрипта)


Одним из потенциальных преимуществ вышеуказанного метода является то, что вы можете также используйте местоположение относительно текущего каталога для значения %TopLevel% (в этом случае, исходя из исходного примера, текущим каталогом будет C:\Users):

Set "TopLevel=LongUserName"

Хотя это будет работать правильно только в том случае, если LongUserName еще не существовало как содержимое пути ранее в дереве.

person Compo    schedule 08.09.2019

Вы можете использовать xcopy вместе с его /S (включая подкаталоги) и /L (перечислите, но не копируйте), поскольку тогда он возвращает относительные пути, поэтому вам не нужно выполнять какие-либо манипуляции со строками, что иногда может быть немного опасным, особенно когда текущий каталог является корнем диска:

xcopy /L /S /I /Y /R ".\*.txt" "\" | find ".\"

Добавленная команда find представляет собой фильтр, удаляющий строку сводки # File(s) из вывод.


Чтобы захватить вывод вышеупомянутой командной строки, просто используйте for /F цикл:

for /F "delims=" %%I in ('
    xcopy /L /S /I /Y /R ".\*.txt" "\" ^| find ".\"
') do (
    rem // Do something with each item:
    echo/%%I
)
person aschipfl    schedule 09.09.2019