Comment obtenir le chemin du dossier à partir du chemin du fichier avec CMD

151

J'ai besoin du chemin d'accès au dossier contenant le fichier cmd. Avec% 0, je peux obtenir le nom du fichier. Mais comment obtenir le nom du dossier?

c: \ temp \ test.cmd >> test.cmd

PS Mon répertoire actuel! = Dossier du script.

Mike Chaliy
la source

Réponses:

310

Pour le nom du dossier et le lecteur, vous pouvez utiliser:

echo %~dp0

Vous pouvez obtenir beaucoup plus d'informations en utilisant différents modificateurs:

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file

The modifiers can be combined to get compound results:
%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only

Ceci est un copier-coller du "for /?" commande à l'invite. J'espère que ça aide.

en relation

Top 10 des astuces DOS Batch (Oui, DOS Batch ...) montre batchparams.bat (lien vers la source comme un point essentiel):

C:\Temp>batchparams.bat c:\windows\notepad.exe
%~1     =      c:\windows\notepad.exe
%~f1     =      c:\WINDOWS\NOTEPAD.EXE
%~d1     =      c:
%~p1     =      \WINDOWS\
%~n1     =      NOTEPAD
%~x1     =      .EXE
%~s1     =      c:\WINDOWS\NOTEPAD.EXE
%~a1     =      --a------
%~t1     =      08/25/2005 01:50 AM
%~z1     =      17920
%~$PATHATH:1     =
%~dp1     =      c:\WINDOWS\
%~nx1     =      NOTEPAD.EXE
%~dp$PATH:1     =      c:\WINDOWS\
%~ftza1     =      --a------ 08/25/2005 01:50 AM 17920 c:\WINDOWS\NOTEPAD.EXE
Wadih M.
la source
Cool. Ai-je besoin d'un score particulier pour modifier la publication wiki de quelqu'un d'autre?
Wadih M.
@Wadih M.: lien généralement utile stackoverflow.com/questions/18557/…
jfs
@Wadih M.: En particulier stackoverflow.com/questions/130654/…
jfs
@Wadih M.: Depuis le lien ci-dessus: "+750 pour éditer les messages de la communauté 'wiki modifiable'"
jfs
Donc, si vous voulez qu'un script cmd définisse le répertoire de travail à l'emplacement du script: cd /d "%~dp0"(de stackoverflow.com/questions/4451668 )
Nigel Touch
52

La réponse acceptée est utile, mais il n'est pas immédiatement évident de savoir comment récupérer un nom de fichier à partir d'un chemin si vous n'utilisez PAS de valeurs transmises. J'ai pu résoudre ce problème à partir de ce fil, mais au cas où d'autres ne seraient pas aussi chanceux, voici comment procéder:

@echo off
setlocal enabledelayedexpansion enableextensions

set myPath=C:\Somewhere\Somewhere\SomeFile.txt
call :file_name_from_path result !myPath!
echo %result%
goto :eof

:file_name_from_path <resultVar> <pathVar>
(
    set "%~1=%~nx2"
    exit /b
)

:eof
endlocal

Maintenant, la :file_name_from_pathfonction peut être utilisée n'importe où pour récupérer la valeur, pas seulement pour les arguments passés. Cela peut être extrêmement utile si les arguments peuvent être passés dans le fichier dans un ordre indéterminé ou si le chemin n'est pas du tout passé dans le fichier.

NightOwl888
la source
Wouh, c'est dingue! Ainsi, les fichiers de commandes Windows fonctionnent dans le même fichier, quelle utilité! Depuis quand était-ce possible?
Luke
2
J'aime que vous puissiez passer des variables à la fois par référence (telle quelle) et par valeur (entourée de "!"). Ok, vous n'avez probablement pas de variables "locales" et de pile d'appels ... mais bon: c'est un script cmd après tout, c'est un grand pas en avant quand même;) Je suis d'accord, partitionner des trucs dans un seul fichier est beaucoup plus pratique que de le diviser en plusieurs fichiers :)
Luke
1
Je pense que "goto: eof" devrait être "goto eof" .. sans les deux points .. car il se cassait pour moi.
A Khudairy le
2
Voir aussi: ss64.com/nt/syntax-args.html - à utiliser %~dp1uniquement pour le lecteur et le chemin.
Andrew
2
@AKhudairy est correct: ss64.com/nt/goto.html Avec les deux-points, le goto saute l'endlocal (et tout ce que vous mettez après, comme une pause). Vous devez également ajouter des "s autour !myPath!si votre chemin contient des espaces (ou si les guillemets font partie de myPath)
Rick
8

Afin de les affecter à des variables, assurez-vous de ne pas ajouter d'espaces devant ou après le signe égal:

set filepath=%~dp1
set filename=%~nx1

Ensuite, vous ne devriez avoir aucun problème.

Franc
la source
5

Au cas où quelqu'un voudrait une méthode alternative ...

S'il s'agit du dernier sous-répertoire du chemin, vous pouvez utiliser ce one-liner:

cd "c:\directory\subdirectory\filename.exe\..\.." && dir /ad /b /s

Cela renverrait ce qui suit:

c:\directory\subdirectory

Le .... revient au répertoire précédent. / ad n'affiche que les répertoires / b est une liste au format simple / s inclut tous les sous-répertoires. Ceci est utilisé pour obtenir le chemin complet du répertoire à imprimer.

marque
la source
Cela fonctionne probablement avec le répertoire actuel, pas un répertoire où se trouve le fichier de script.
Mike Chaliy
4

J'ai eu le même problème dans ma boucle où je voulais extraire les fichiers zip dans le même répertoire, puis supprimer le fichier zip. Le problème était que 7z nécessite le dossier de sortie, je devais donc obtenir le chemin du dossier de chaque fichier. Voici ma solution:

FOR /F "usebackq tokens=1" %%i IN (`DIR /S/B *.zip` ) DO (
  7z.exe x %%i -aoa -o%%i\..
) 

%% i était un chemin de nom de fichier complet et% ii \ .. renvoie simplement le dossier parent.

J'espère que ça aide.

Gico
la source
Rapide et sale. J'aime ça! Jamais pensé que vous étendiez à froid un chemin de fichier avec "\ .." et que vous vous retrouviez avec le dossier parent.
Oliver R.
Cela a fonctionné pour moi sur Win10: FOR / R "C: \ sourceDir"% I IN (* .gz) DO C: \ 7-Zip64 \ 7z.exe x "% I" -aou -o% I \ .. \
b3wii
Oui! Cela contourne le problème que% ~ dp1 (etc.) ne fonctionne que sur% 0,% 1,% 2 etc.
Artelius
3

Si la réponse acceptée par Wadih n'a pas fonctionné pour vous, essayez echo %CD%

Naguib Ihab
la source
0

Cela a été mis en place avec un exemple de cmd

@Echo off

Echo ********************************************************
Echo *  ZIP Folder Backup using 7Zip                        *
Echo *  Usage: Source Folder, Destination Drive Letter      *
Echo *  Source Folder will be Zipped to Destination\Backups *
Echo ********************************************************
Echo off

set year=%date:~-4,4%
set month=%date:~-10,2%
set day=%date:~-7,2%
set hour=%time:~-11,2%
set hour=%hour: =0%
set min=%time:~-8,2%

SET /P src=Source Folder to Backup: 
SET source=%src%\*
call :file_name_from_path nam %src%
SET /P destination=Backup Drive Letter:
set zipfilename=%nam%.%year%.%month%.%day%.%hour%%min%.zip
set dest="%destination%:\Backups\%zipfilename%"


set AppExePath="%ProgramFiles(x86)%\7-Zip\7z.exe"
if not exist %AppExePath% set AppExePath="%ProgramFiles%\7-Zip\7z.exe"

if not exist %AppExePath% goto notInstalled

echo Backing up %source% to %dest%

%AppExePath% a -r -tzip %dest% %source%

echo %source% backed up to %dest% is complete!

TIMEOUT 5

exit;

:file_name_from_path <resultVar> <pathVar>
(
    set "%~1=%~nx2"
    exit /b
)


:notInstalled

echo Can not find 7-Zip, please install it from:
echo  http://7-zip.org/

:end
PAUSE
Steve Seymour
la source