2010-03-07 4 views
12

ho bisogno di trovare il nome della directory principale di un file in DOSGet nome directory padre per un particolare file utilizzando DOS batch scripting

ad es.

Supponiamo questa è la directory

C:\test\pack\a.txt 

Ho uno script che mi chiede il nome del file

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

ora lo script dovrebbe restituire solo il nome principale del file.

pack   

e NON l'intero percorso genitore del file.

c:\test\pack 

risposta

9

vedere this domanda

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

for /F "tokens=* delims=;" %%i IN (%mydir%) DO call :LAST_FOLDER %%i 
goto :EOF 

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

set LAST=%1 
SHIFT 

goto :LAST_FOLDER
+0

Grazie .. U r genio :) .. funziona perfettamente –

+0

Non vedo come possa funzionare. % ~ p1 non funziona per me. Funziona solo con% ~ dp0 o% ~ p0. – djangofan

+0

@djangofan Lo script prende un percorso come argomento e restituisce il nome della directory del percorso. – asdfg

1

è possibile utilizzare un VBScript, ad esempio, salvare il seguito come getpath.vbs

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

poi sulla linea di comando o in batch, fare questo

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

Se si desidera un metodo batch, è possibile esaminare for /?.

10

La prima risposta di cui sopra non funziona se il nome della directory padre contiene uno spazio. Le seguenti opere:

@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 

Richiamo quanto sopra con il parametro di "C: \ Temp \ Parent Dir Con Spazio \ myfile.txt" dà seguito:

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

I lavori di cui sopra, sostituendo gli spazi con i due punti (questi non dovrebbero esistere nei percorsi di Windows), quindi sostituendo i delimitatori di directory con spazi in modo che le singole directory vengano passate a getparentdir come argomenti separati. Funzione getparentdir esegue il ciclo finché non trova il suo ultimo argomento. Alla fine, tutti i due punti nel risultato vengono sostituiti da spazi.

+0

è possibile farlo funzionare per nomi di file che includono virgole? caso speciale lo so, mi chiedo solo se sarebbe una semplice aggiunta o un sacco di codice in più. grazie – GeorgeCostanza

1

Ecco un modo che non utilizza CALL e credo sia più veloce.Based on jeb's splitting function (potrebbe non riuscire se il nome della directory contiene !):

@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 
+0

questo funziona benissimo. c'è un modo semplice per aggiungere casi speciali per punti esclamativi, ecc. oppure lo scripting DOS è troppo limitato? – GeorgeCostanza

0

Ecco un'altra soluzione:

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' estratti nome dal percorso memorizzato nella variabile %% I
cd: parametro '/ D' aggiunto per passare tra i dischi anche

1

ho trovato questa combinazione di approcci dalle risposte di djangofan e paranoico di essere sia, semplice e perfettamente s ufficient, quando alzando lo sguardo directory principale del mio script:

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

Dal momento che si desidera lavorare su input dell'utente, invece, è necessario fare un certo lavoro aggiuntivo minimo, per gestire le variazioni di legge come C: \ foo \ bar \ a. txt vs. C: \ foo \ bar \ a.txt o c: /foo/bar/a.txt. Questo potrebbe quindi lavorare per voi:

@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 
7

Può essere molto semplice per ottenere la cartella principale del file batch:

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

E per un genitore di un percorso di file come per la domanda:

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

Ho trovato questo utile per trovare una cartella genitore che era un paio di directory sopra il file batch. Basta aggiungere '\ ..' dopo '% ~ dp0 \ .' per salire al livello di una cartella. Esempio: 'per %% a in ("% ~ dp0 \. \ .. \ .. \ .. ") imposta" parent = %% ~ nxa "' – Toomaja

1

L'idea di DaDummy ha funzionato in funzioni più pratiche riutilizzabili. Anche il primo carattere di _full_path è ora incluso.

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