it-swarm.com.ru

Получить имя родительского каталога для определенного файла, используя пакетные сценарии DOS

Мне нужно найти имя родительского каталога для файла в DOS

например.

Предположим, что это каталог

C:\test\pack\a.txt

У меня есть скрипт, который спрашивает меня имя файла

C:\\>getname.bat     
enter file name: c:\test\pack\a.txt   

теперь скрипт должен возвращать только родительское имя файла. 

pack           

а НЕ полный родительский путь к файлу.

c:\test\pack   
15
user288167

увидеть это вопрос

@echo OFF 
 set mydir = "% ~ p1" 
 SET mydir =% mydir:\=;% 

 for/F "tokens = * delims =;" %% i IN (% mydir%) DO вызвать: LAST_FOLDER %% i 
 goto: EOF 

: LAST_FOLDER 
 if "% 1" == "" (
 @echo% LAST % 
 goto: EOF 
) 

 set LAST =% 1 
 SHIFT 

 goto: LAST_FOLDER
11
asdfg

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

@echo off
setlocal

set ParentDir=%~p1
set ParentDir=%ParentDir: =:%
set ParentDir=%ParentDir:\= %
call :getparentdir %ParentDir%
set ParentDir=%ParentDir::= %

echo ParentDir is %ParentDir%
goto :EOF

:getparentdir
if "%~1" EQU "" goto :EOF
Set ParentDir=%~1
shift
goto :getparentdir

Вызов выше с параметром «C:\Temp\Parent Dir With Space\myfile.txt» дает следующее:

>GetParentDir "C:\Temp\Parent Dir With Space\myfile.txt"
ParentDir is Parent Dir With Space

Вышеприведенное работает путем замены пробелов двоеточиями (их не должно быть в путях Windows), а затем замены разделителей каталогов пробелами, чтобы отдельные каталоги передавались в getparentdir в качестве отдельных аргументов. Функция getparentdir зацикливается, пока не найдет свой последний аргумент. Наконец, любые двоеточия в результате заменяются пробелами.

12
duncanm

Получить родительскую папку командного файла может быть очень просто:

@echo off
for %%a in ("%~dp0\.") do set "parent=%%~nxa"
echo %parent%

И для родителя пути к файлу согласно вопросу:

@echo off
for %%a in ("c:\test\pack\a.txt") do for %%b in ("%%~dpa\.") do set "parent=%%~nxb"
echo %parent%
8
foxidrive

Идея DaDummy проработана в более практичных многоразовых функциях. Также теперь включен первый символ _full_path.

set map=D:\test1\test2\test3\test4.txt
call:get_parent_path "%map%"
echo full_path is %_full_path%
call:get_parent_path %_full_path%
echo full_path is %_full_path%
call:get_last_path %_full_path%
echo last_path is %_last_path%
goto :eof

:get_parent_path
set "_full_path=%~dp1"
:_strip
if not "%_full_path:~-1%"=="\" if not "%_full_path:~-1%"=="/" goto:_strip_end
set "_full_path=%_full_path:~0,-1%"
goto:_strip
:_strip_end
exit /b

:get_last_path
set "_last_path=%~nx1"
exit /b

::result:
::full_path is D:\test1\test2\test3
::full_path is D:\test1\test2
::last_path is test2
1
GerH

Я нашел, что эта комбинация подходов из ответов djangofan и paranoid является одновременно простой и совершенно достаточной при поиске родительского каталога моего скрипта:

set FULL_PATH=%~dp0
set FULL_PATH=%FULL_PATH:~1,-1%
for %%i in ("%FULL_PATH%") do set "PARENT_FOLDER=%%~ni"
echo %PARENT_FOLDER%

Поскольку вместо этого вы хотите поработать с пользовательским вводом, вам нужно проделать минимальную дополнительную работу, чтобы обработать допустимые варианты, такие как C:\foo\bar\a.txt и C:\foo\bar\a.txt или c:/Foo/бар/a.txt. Тогда это может сработать для вас:

@setlocal
@echo off

call:GET_PARENT_FOLDER C:\foo\bar\a.txt
echo %PARENT_FOLDER%
call:GET_PARENT_FOLDER C:\foo\bar\\a.txt
echo %PARENT_FOLDER%
call:GET_PARENT_FOLDER c:/foo/bar/a.txt
echo %PARENT_FOLDER%

pause
goto:EOF

:GET_PARENT_FOLDER
:: Strip the filename, so we get something like this: 'C:\foor\bar\'
set "_FULL_PATH=%~dp1"

:: Strips all dangling '\' and '/' in a loop, so the last folder name becomes accessible
:_STRIP
if not "%_FULL_PATH:~-1%"=="\" if not "%_FULL_PATH:~-1%"=="/" goto:_STRIP_END
set "_FULL_PATH=%_FULL_PATH:~1,-1%"
goto:_STRIP
:_STRIP_END

:: We need the context of a for-loop for the special path operators to be available
for %%i in ("%_FULL_PATH%") do set "PARENT_FOLDER=%%~ni"

goto:EOF
1
DaDummy

вы можете использовать VBScript, например, сохранить ниже как getpath.vbs

Set objFS = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
strFile = objArgs(0)
WScript.Echo objFS.GetParentFolderName(strFile)

затем в командной строке или в вашем пакете, сделайте это

C:\test>cscript //nologo getpath.vbs c:\test\pack\a.txt
c:\test\pack

Если вам нужен пакетный метод, вы можете посмотреть на for /?.

  %~fI        - expands %I to a fully qualified path name
  %~dI        - expands %I to a drive letter only
  %~pI        - expands %I to a path only
1
ghostdog74

Вот способ, который не использует CALL, и я считаю, что это быстрее . На основе функции разбиения jeb (может произойти сбой, если имя каталога содержит !):

@echo off

set "mydir=%~p1"
SET mydir=%mydir:~0,-1%

setlocal EnableDelayedExpansion
set LF=^


rem ** Two empty lines are required

for %%L in ("!LF!") DO (
    set "dir_name=!mydir:\=%%L!"
)
for /f "delims=" %%P in (""!dir_name!"") do set "dn=%%~P"
echo %dn%

exit /b 0 
1
npocmaka

Вот еще одно решение:

SET LAST=%CD%
SET PARENTNAME=NONE
cd /D C:\test\pack
FOR %%I in (%CD%) do SET PARENTNAME=%%~nI
cd /D %LAST%
ECHO %PARENTNAME%

%% ~ nI: '~ n' извлекает имя из пути, хранящегося в переменной %% I
Добавлен параметр cd: '/ D' для переключения между дисками.

0
paranoid