How to get folder path from file path with CMD - path

I need path to the folder that contains cmd file.
With %0 I can get the file name. But how to get the folder name?
c:\temp\test.cmd >> test.cmd
P.S. My current directory != folder of the script.

For the folder name and drive, you can use:
echo %~dp0
You can get a lot more information using different modifiers:
%~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
This is a copy paste from the "for /?" command on the prompt.
Related
Top 10 DOS Batch tips (Yes, DOS Batch...) shows batchparams.bat (link to source as a gist):
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

The accepted answer is helpful, but it isn't immediately obvious how to retrieve a filename from a path if you are NOT using passed in values. I was able to work this out from this thread, but in case others aren't so lucky, here is how it is done:
#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
Now the :file_name_from_path function can be used anywhere to retrieve the value, not just for passed in arguments. This can be extremely helpful if the arguments can be passed into the file in an indeterminate order or the path isn't passed into the file at all.

In order to assign these to variables, be sure not to add spaces in front or after the equals sign:
set filepath=%~dp1
set filename=%~nx1
Then you should have no issues.

In case anyone wants an alternative method...
If it is the last subdirectory in the path, you can use this one-liner:
cd "c:\directory\subdirectory\filename.exe\..\.." && dir /ad /b /s
This would return the following:
c:\directory\subdirectory
The .... drops back to the previous directory.
/ad shows only directories
/b is a bare format listing
/s includes all subdirectories. This is used to get the full path of the directory to print.

I had same problem in my loop where i wanted to extract zip files in the same directory and then delete the zip file. The problem was that 7z requires the output folder, so i had to obtain the folder path of each file. Here is my solution:
FOR /F "usebackq tokens=1" %%i IN (`DIR /S/B *.zip` ) DO (
7z.exe x %%i -aoa -o%%i\..
)
%%i was a full filename path and %ii\.. simply returns the parent folder.
hope it helps.

In case the accepted answer by Wadih didn't work for you, try echo %CD%

This was put together with some edited example 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

IMHO the simplest yet most powerful method to get the full path of a file is:
Start Notepad
Copy and Paste the following text:
#echo %1 | clip 3
Save the file as "CopyAsPath.bat"
Now you can either
drag a file over that batch
or
copy it into your SendTo menu folder (%USERPROFILE%\AppData\Roaming\Microsoft\Windows\SendTo)
Whether you follow the option 1 or the option 2, one millisecond later you can either
"press Ctrl-V"
or
use "Right Mouse Click -> Paste"
to paste the full path+filename wherever you want.
Simple, powerful, and without using any external Windows tool.

Related

DIR but select specific parts of file names

I have the habit for years to use this very easy and convenient .BAT file to create a simple TXT file of all my files in a directory:
dir *.* > LIST.TXT
but the result includes many pieces of information that I don't need
Now I have many files in a directory in this way:
file 01 [shYddYJQIGfffY].xyz
second file 00008 [shYddYJQIfGf11dfzrffY].exe
filex [shGffY].sys
file that i don't need.txt
many other files that i don't need.bat
1/ which command line can I use with DIR (or anything else) to have in the final LIST.txt files only those information? only the value between [ and ]
Expected result:
shYddYJQIGfffY
shYddYJQIfGf11dfzrffY
shGffY
2/ how to edit the .BAT file to add the string MYRESULT before each of those results, like:
MYRESULT shYddYJQIGfffY
MYRESULT shYddYJQIfGf11dfzrffY
MYRESULT shGffY
Use a for loop (see for /?):
for /f "tokens=2 delims=[]" %%a in ('dir /b *[*].*') do echo MYRESULT %%a
This for /f loop takes the output of dir /b *[*].* (filtering for relevant files, bare format) line per line and splits it into three parts, first token the part before the first [, token2 the part between [ and ]. and a third part after that. You need the second token only. Then just echo the string together with the extracted substring, done.

How do I create a batch file that reads a file and writes a substring into another file?

I currently have an exported text file (output.txt) from a Clear-Case command that I need to parse. It looks like this:
Comparing the following:
R1.PROD.V1#\VOB_pvob
R2.PROD.V1#\VOB_pvob
Differences:
>> M:\ACME_PROD\src\ACME##
>> M:\ACME_PROD\src\ACME\file 2.txt##
>> M:\ACME_PROD\src\ACME\file 1.txt##
>> M:\ACME_PROD\src\ACME\file 3.txt##
What I would like to do is use the findstr command to filter the strings that are contained between the ">> " and "##" strings to get an output file that looks like this (with quotes if possible:
"M:\ACME_PROD\src\ACME"
"M:\ACME_PROD\src\ACME\file 2.txt"
"M:\ACME_PROD\src\ACME\file 1.txt"
"M:\ACME_PROD\src\ACME\file 3.txt"
I am new to writing batch files and so I don't exactly know where to start. I have managed to find code that can loop through the lines of a text file and separate code for the findstr command, but I get stuck trying to put it all together!
Best regards,
Andrew
Here you go
setlocal enabledelayedexpansion
for /f "skip=1 tokens=* delims=> " %%a in ('"findstr /r [\w^>*] output.txt"') do (
set line=%%a
set line=!line:#=!
echo "!line!" >>new.txt
)
The filtered strings will be outputted into new.txt.

Batch : getting the last folder name from a absolute path

I am using a Batch script to automatically backup files to my NAS and I need to get the last folder name from an absolute path, like from "C:\Things\Folder" to "Folder"
It's a bit of a hack, but you can use:
Set NasPath=C:\Things\Folder
Set NasFolder=%NasPath%
:GetFolder
Set GetFolderTemp=%NasFolder:*\=%
If Not %GetFolderTemp%==%NasFolder% (
Set NasFolder=%GetFolderTemp%
Goto :GetFolder
)
Echo NasPath =%NasPath%
Echo NasFolder=%NasFolder%
Exit /B
Whatever you do, don't put quotes around any part of the Set NasPath=... statement. Use quotes this way:
Set FromPath=C:\Program Files\Blah
Set NasPath=C:\Things\Folder
RoboCopy "%FromPath%" "%NasPath%"
Do not use quotes this way:
Set FromPath="C:\Program Files\Blah"
Set NasPath="C:\Things\Folder"
RoboCopy %FromPath% %NasPath%
To not have any issue with space, I propose this code:
Set NasPath=C:\Things\My Space\Folder
Set GetFolderTemp=%NasPath%
:GetFolder
FOR /F "tokens=1,* delims=\" %%1 IN ("%GetFolderTemp%") do (
set NasFolder=%%1
set GetFolderTemp=%%2
)
if not "a%GetFolderTemp%"=="a" goto :GetFolder
echo %NasFolder%
Assuming C:\Program Files\Mickey\Mouse-like paths (without quotes), you could also use the following code:
setlocal EnableDelayedExpansion
set path=C:\Program Files\Microsoft\Mickey\Mouse
:shift
for /f "tokens=1* delims=\/" %%i in ( "!path!" ) do (
set folder=%%i
set path=%%j
)
if not [!path!] == [] goto :shift
echo folder: !folder!
endlocal

Make a relative path in batch file

I have a batch file that I wont know what drive letter it will be as I will be moving around alot.
For example:
The adobe files reside in: J:\Files\New folder\USB\Adob
The batch file is executed from: J:\Files\New folder\USB\USBSTICK
So I tried the code:
xcopy /s /y "%~dp0\..\..\USB\Adob\*" "C:\Program Files\"
But it will not copy the files. How can I get it dynamic?
As the drive letter seems to be the relative part of your scenario. I believe this should work better for you, unless I have misunderstood you.
xcopy /s /y "%~d0\Files\New folder\USB\Adob\*" "C:\Program Files\"
For more variables that you can use follow these steps:
From CMD, type for /? and read at the bottom.
%~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
%~$PATH:I - searches the directories listed in the PATH
environment variable and expands %I to the
fully qualified name of the first one found.
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string
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
%~dp$PATH:I - searches the directories listed in the PATH
environment variable for %I and expands to the
drive letter and path of the first one found.
%~ftzaI - expands %I to a DIR like output line
In the above examples %I and PATH can be replaced by other valid
values. The %~ syntax is terminated by a valid FOR variable name.
Picking upper case variable names like %I makes it more readable and
avoids confusion with the modifiers, which are not case sensitive.
From my understanding of your hierarchy, this would also work:
xcopy /s /y "..\Adob\*" "C:\Program Files\"
since J:\Files\New folder\USB is a common prefix, and you're running the batch file from J:\Files\New folder\USB\USBSTICK, this should work no matter what drive letter you're dealing with.
I'm not sure that I fully understand your problem. But it seems to me that there are several solutions that would solve the problem as I understand it.
If the paths are always fixed, but only the drive letter may vary, you could just use a relative path:
xcopy /s /y "..\Adob\*" "C:\Program Files\"
Calling the batch program from any drive would then work as expected provided the batch file always exists in USBSTICK which exists in the same dir as Adob.
If the source path can vary, just replace the varying part with a parameter, and call the batch file with the correct path:
xcopy /s /y "%1\*" "C:\Program Files\"
Calling the batch program from any drive AND location would then work as expected when you supply it with the correct path:
xcopybatch J:\Files\New folder\USB\Adob
Try without the "\", as it is part of %~dp0. I mean, the contents of %~dp0 will always end with a "\".
Example:
xcopy /s /y "%~dp0..\..\USB\Adob\*" "C:\Program Files\"
Edit
Just in case ...
is Adob\* or Adob\*.* ??

DOS batch: get last folder from relative path

I have the following values in a DOS batch file (for example...):
..\Apple\Jones
..\Banana\Smith
..\Pear\Wilson
I need to extract the last name values ("Jones", "Smith", "Wilson") from each value. What one technique can I use that will always give me these substring values?
According to this topic : What is the best way to do a substring in a batch file?
I suggest you to use
%~n0
I already wrote a function for that. You give it any path and it returns you only it's filename or pathname. Works for any path: Url, Windows path, Unix path, etc...
Copy this function at the end of your batch script: (Instructions below)
rem ===========================================================================
:Name_From_Path
SetLocal
set _TMP_FOLDERNAME=%1
for %%g in ("%_TMP_FOLDERNAME%") do set _TMP_FOLDERNAME=%%~nxg
EndLocal & set _Name_From_Path=%_TMP_FOLDERNAME%
goto :EOF
rem ===========================================================================
Usage:
CALL :Name_Of_Path ..\Apple\Jones
ECHO %_Name_From_Path%
Result: Jones

Resources