How do I split the filename out of a full path in batch scripting?
-
2possible duplicate of [Batch Extract path and filename from a variable](http://stackoverflow.com/questions/15567809/batch-extract-path-and-filename-from-a-variable) – Gab Mar 31 '15 at 08:33
6 Answers
@echo off
Set filename=C:\Documents and Settings\All Users\Desktop\Dostips.cmd
For %%A in ("%filename%") do (
Set Folder=%%~dpA
Set Name=%%~nxA
)
echo.Folder is: %Folder%
echo.Name is: %Name%
But I can't take credit for this; Google found this at http://www.dostips.com/forum/viewtopic.php?f=3&t=409

- 5,595
- 2
- 39
- 62
-
1Thanks! This worked for me too. I'm reading in a list of folders from a file and formatting them. I used this: "for /F "tokens=1 delims=" %%A in (list_of_files.txt) do (" – Mike Q Jun 12 '13 at 16:43
-
1Might be nice to show how to get just the file name. (Without the extension.) – Vaccano Oct 17 '13 at 20:43
-
3%~nI - expands %I to a file name only <- taken direct from teh DOS "for -help" output. – Pete Stensønes Oct 18 '13 at 09:03
-
6To help clarify, d means include the drive, p include the path, n include the file name, x include the extension. – makhdumi Nov 20 '13 at 22:17
Parse a filename from the fully qualified path name (e.g., c:\temp\my.bat) to any component (e.g., File.ext).
Single line of code:
For %%A in ("C:\Folder1\Folder2\File.ext") do (echo %%~fA)
You can change out "C:\Folder1\Folder2\File.ext" for any full path and change "%%~fA" for any of the other options you will find by running "for /?" at the command prompt.
Elaborated Code
set "filename=C:\Folder1\Folder2\File.ext"
For %%A in ("%filename%") do (
echo full path: %%~fA
echo drive: %%~dA
echo path: %%~pA
echo file name only: %%~nA
echo extension only: %%~xA
echo expanded path with short names: %%~sA
echo attributes: %%~aA
echo date and time: %%~tA
echo size: %%~zA
echo drive + path: %%~dpA
echo name.ext: %%~nxA
echo full path + short name: %%~fsA)
Standalone Batch Script
Save as C:\cmd\ParseFn.cmd.
Add C:\cmd to your PATH environment variable and use it to store all of you reusable batch scripts.
@echo off
@echo ::___________________________________________________________________::
@echo :: ::
@echo :: ParseFn ::
@echo :: ::
@echo :: Chris Advena ::
@echo ::___________________________________________________________________::
@echo.
::
:: Process arguements
::
if "%~1%"=="/?" goto help
if "%~1%"=="" goto help
if "%~2%"=="/?" goto help
if "%~2%"=="" (
echo !!! Error: ParseFn requires two inputs. !!!
goto help)
set in=%~1%
set out=%~2%
:: echo "%in:~3,1%" "%in:~0,1%"
if "%in:~3,1%"=="" (
if "%in:~0,1%"=="/" (
set in=%~2%
set out=%~1%)
)
::
:: Parse filename
::
set "ret="
For %%A in ("%in%") do (
if "%out%"=="/f" (set ret=%%~fA)
if "%out%"=="/d" (set ret=%%~dA)
if "%out%"=="/p" (set ret=%%~pA)
if "%out%"=="/n" (set ret=%%~nA)
if "%out%"=="/x" (set ret=%%~xA)
if "%out%"=="/s" (set ret=%%~sA)
if "%out%"=="/a" (set ret=%%~aA)
if "%out%"=="/t" (set ret=%%~tA)
if "%out%"=="/z" (set ret=%%~zA)
if "%out%"=="/dp" (set ret=%%~dpA)
if "%out%"=="/nx" (set ret=%%~nxA)
if "%out%"=="/fs" (set ret=%%~fsA)
)
echo ParseFn result: %ret%
echo.
goto end
:help
@echo off
:: @echo ::___________________________________________________________________::
:: @echo :: ::
:: @echo :: ParseFn Help ::
:: @echo :: ::
:: @echo :: Chris Advena ::
:: @echo ::___________________________________________________________________::
@echo.
@echo ParseFn parses a fully qualified path name (e.g., c:\temp\my.bat)
@echo into the requested component, such as drive, path, filename,
@echo extenstion, etc.
@echo.
@echo Syntax: /switch filename
@echo where,
@echo filename is a fully qualified path name including drive,
@echo folder(s), file name, and extension
@echo.
@echo Select only one switch:
@echo /f - fully qualified path name
@echo /d - drive letter only
@echo /p - path only
@echo /n - file name only
@echo /x - extension only
@echo /s - expanded path contains short names only
@echo /a - attributes of file
@echo /t - date/time of file
@echo /z - size of file
@echo /dp - drive + path
@echo /nx - file name + extension
@echo /fs - full path + short name
@echo.
:end
:: @echo ::___________________________________________________________________::
:: @echo :: ::
:: @echo :: ParseFn finished ::
:: @echo ::___________________________________________________________________::
:: @echo.

- 1,063
- 9
- 17
-
'Elaborated code' potentially has an error; d is not directory entry? Or different effects when in a batch file? As the 'standalone batch script' indicates? – user3082 Sep 08 '19 at 11:22
@echo off
Set filename="C:\Documents and Settings\All Users\Desktop\Dostips.cmd"
call :expand %filename%
:expand
set filename=%~nx1
echo The name of the file is %filename%
set folder=%~dp1
echo It's path is %folder%

- 101
- 2
- 5
-
When I run this, it outputs the lines twice. I'm not sure how to fix this. This is the output: `The name of the file is Dostips.cmd It's path is C:\Documents and Settings\All Users\Desktop\ The name of the file is It's path is` – Ste Jan 19 '20 at 23:35
-
**This** only happens when the path doesn't exist. Any way around that without an if statement? But this is a neat solution, so thank you. – Ste Jan 20 '20 at 00:24
-
No that wasn't it either. If I add `echo anther line` to the bottom of that code, it behaves the same. – Ste Jan 20 '20 at 00:33
Continuing from Pete's example above, to do it directly in the cmd window, use a single %
, eg:
cd c:\test\folder A
for %X in (*)do echo %~nxX
(Note that special files like desktop.ini will not show up.)
It's also possible to redirect the output to a file using >>
:
cd c:\test\folder A
for %X in (*)do echo %~nxX>>c:\test\output.txt
For a real example, assuming you want to robocopy all files from folder-A to folder-B (non-recursively):
cd c:\test\folder A for %X in (*)do robocopy . "c:\test\folder B" "%~nxX" /dcopy:dat /copyall /v>>c:\test\output.txt
and for all folders (recursively):
cd c:\test\folder A for /d %X in (*)do robocopy "%X" "C:\test\folder B\%X" /e /copyall /dcopy:dat /v>>c:\test\output2.txt

- 86,231
- 106
- 366
- 634
-
While using this I just discovered if you use these techniques with robocopy you also need to remember to remove the last backslash in the source directory. It would be useful if there was an example which uses `%~dpX` as source. – AnnanFay Mar 27 '17 at 14:30
Just want to share my 2c after I need this for my batch script. Using for
is not helping at all since I want a literal dir and filemask.
ie. given the c:\dir1\subdir\*.asm
, I need both literal c:\dir1\subdir
and *.asm
for further processing
:parsepathname pathname dirname filename
@echo OFF
if "%~3"=="" exit /b -1 ERROR!
setlocal enableDelayedExpansion
set "dirname="
set "filename=%~1"
set "check=%filename:\=%"
if "%check%"=="%filename%" goto pfn_Love1Done
set "ctr=0" & set "pathname=%~1" & set "filename="
:pfn_Love1
if ctr LSS -260 exit /b -2 ERROR!
set /a "ctr-=1"
set "ch=!pathname:~%ctr%,1!"
if not "%ch%"=="\" goto pfn_Love1
set "dirname=!pathname:~0,%ctr%!"
set /a "ctr+=1"
set "filename=!pathname:~%ctr%!"
:pfn_Love1Done
rem echo DEBUG: pathname="%pathname%" dirname="%dirname%" filename="%filename%"
endlocal & set "%~2=%dirname%" & set "%~3=%filename%"
exit /b
call with
call %pathname% dirname filename,
dirnameand
pathname

- 95
- 3
-
`@(set "%~2=%~dp0" & set "%~3=%~nx1")` (yes, as the one and only line) - only difference is the backslash at the end of the folder path. – Stephan Mar 03 '23 at 21:54
-
No. As I said, I dont want the wildcard to be interpreted as filename. I need the literal wildcard itself, for example to be processed further by `for /r dir in (wildcard)`. All solutions presented here, including yours, will translate `%~nxf` as the last filename found. NOT the wildcard itself. that's a HUGE different. Maybe most users don't need my solution, I just presented it for those 1% users who need it and do not know how. – user6801759 Mar 04 '23 at 07:20
-
Of course, mine is not the only solution for that requirement. You can, for example substitute the path with empty string `set filename="%pathname:%~dpf/=%"` works most of the time, still have to be checked if pathname containing drive letter or whether if it has any dir portion at all. – user6801759 Mar 04 '23 at 07:44
-
Sorry, misinterpreted your problem (my line works fine *only* if no file matches the mask) – Stephan Mar 04 '23 at 08:32
I don't know that much about batch files but couldn't you have a pre-made batch file copied from the home directory to the path you have that would return a list of the names of the files then use that name?
Here is a link I think might be helpful in making the pre-made batch file.

- 4,266
- 9
- 28
- 48