Getting parent directory not working in windows 8 batch file - windows

i have a folder structure as
c:\name\myname
I wrote a batch file
test.bat
#echo off
echo %CD%
echo %CD%\..
set k=%CD%
set c=%k%\..
echo %k%
echo %c%
pause
Output
c:\name\myname
c:\name\myname\\..
c:\name\myname
c:\name\myname\\..
Expected Output
c:\name\myname
c:\name
c:\name\myname
c:\name
I have installed windows 8 OS. I want to get parent directory from current directory. May be i don't know the correct syntax to get parent directory.

There are two ways to obtain a reference to a file/folder: arguments to batch files and for command. This second option is what we will use here. As it is not clear what parent do you need, let's see how to obtain each
1 - Get parent of current active directory
for %%a in (..) do echo %%~fa
get a reference to the parent of the current active folder inside the for replaceable parameter %%a and once we have the reference, get the full path to it
2 - Get parent of the folder holding the batch file
for %%a in ("%~dp0.") do echo %%~dpa
same idea. %0 is a reference to the current batch file, so %~dp0 is the drive and path where the batch file is stored. This value ends in a backslash, so, to get a reference to the folder an aditional dot is added. Once we have the reference to the folder holding the batch file in %%a, %%~dpa will return the drive and path where the element referenced in %%a is stored. As %%a is the folder holding the batch file, %%~dpa is the parent, the folder where is stored the folder with the batch.

Related

How to recursively delete all folders of a folder tree unless they contain a file with certain file extension?

How to go though a directory tree and delete all directories unless they contain a file with a particular file extension?
I tried Robocopy thinking the folders were empty. But all the folders have hidden files. So I need something that will take every folder in a directory that does not have a .pdf for example in it and delete it.
The task is to delete all directories/folders not containing a PDF file and also not containing a subdirectory/subfolder containing a PDF file. Let us look on an example to better understand the directory/folder deletion task.
The directory C:\Temp contains following subfolders and files:
Folder 1
Subfolder A
File 1A.txt
Subfolder B
File 1B.txt
Subfolder C
File 1C.pdf
File 1.cmd
Folder 2
Subfolder A
Subfolder B
File 2B.pdf
Subfolder C
File 2C.pdf
File 2.jpg
Folder 3
Subfolder A
File 3A.log
Subfolder B
File 3.doc
Last Folder & End
Subfolder A
Last File A.xls
Subfolder B
Subfolder C
Last File C.pdf
A folder is formatted bold. A hidden folder is formatted bold and italic. A hidden file is formatted italic.
The wanted folders and files after running the batch file should be:
Folder 1
Subfolder C
File 1C.pdf
File 1.cmd
Folder 2
Subfolder B
File 2B.pdf
Subfolder C
File 2C.pdf
File 2.jpg
Last Folder & End
Subfolder C
Last File C.pdf
This result can be achieved by executing following batch file:
#echo off
goto MainCode
:ProcessFolder
for /F "delims=" %%I in ('dir "%~1" /AD /B 2^>nul') do call :ProcessFolder "%~1\%%I"
if exist "%~1\*.pdf" goto :EOF
for /F "delims=" %%I in ('dir "%~1" /AD /B 2^>nul') do goto :EOF
if /I "%~1\" == "%BatchFilePath%" goto :EOF
rd /Q /S "%~1"
goto :EOF
:MainCode
setlocal EnableExtensions DisableDelayedExpansion
set "BatchFilePath=%~dp0"
if exist "C:\Temp\" cd /D "C:\Temp" & call :ProcessFolder "C:\Temp"
endlocal
Doing something recursively on a directory tree requires having a subroutine/function/procedure which calls itself recursively. In the batch file above this is ProcessFolder.
Please read the answer on Where does GOTO :EOF return to? The command goto :EOF is used here to exit the subroutine ProcessFolder and works only as wanted with enabled command extensions. FOR and CALL as used here require also enabled command extensions.
The main code of the batch file first enables explicitly the command extensions required for this batch file and disables delayed environment variable expansion to process correct also folders with an exclamation mark in name. This is the default environment on Windows, but it is better here to explicitly set this environment because the batch file contains the command RD with the options /Q /S which can be really very harmful on execution from within wrong environment or directory.
The subroutine ProcessFolder is not at end of the batch file as usual with a goto :EOF above to avoid an unwanted fall through to the command lines of the subroutine after finishing the entire task. For safety reasons the subroutine is in the middle of the batch file. So if a user tries to execute the batch file on Windows 95/98 with no support for command extensions nothing bad happens because first goto MainCode is executed successfully as expected, but SETLOCAL command line, calling the subroutine and last also ENDLOCAL fail and so no directory was deleted by this batch file designed for Windows with cmd.exe as Windows command processor instead of command.com.
The main code sets also current directory to the directory to process. So C:\Temp itself is never deleted by this code because of Windows prevents the deletion of a directory which is the current directory of any running process or contains a file opened by a running process with file access permission set to prevent other processes to delete the file while being opened by the process.
Next is called subroutine ProcessFolder with argument C:\Temp to process this folder recursively.
Last the initial environment is restored which includes also initial current directory on starting the batch file if this directory still exists.
The command for /D is usually used to do something on all subdirectories of a directory. But this is not possible here because FOR always ignores directories and files with hidden attribute set. For that reason it is necessary to use command DIR to get a list of all subdirectories in current directory including directories with hidden attribute set.
The command line dir "%~1" /AD /B 2>nul is executed by FOR in a separate command process started with cmd.exe /C in background. This is one reason why this batch file is quite slow. The other reason is calling the subroutine again and again which cause internally in cmd.exe to save and restore environment again and again.
Please read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
For each subdirectory in a directory the subroutine ProcessFolder calls itself. The first FOR loop in the subroutine is left if a directory does not contain one more subdirectory.
Then the subroutine checks in current directory if there is at least one *.pdf file. The IF condition used here is true even if the directory contains only a hidden PDF file. In this case the subroutine is exited without doing anything as this directory contains definitely a PDF file and therefore must be kept according to the requirements of the folder deletion task.
Next is checked if the current directory still contains at least one subdirectory as in this case the current directory must be also kept as one of its subdirectories contains at least one PDF file.
Last the subroutine checks if the current directory contains by chance the batch file as this directory must be also kept to finish the processing of the batch file.
Otherwise the current directory is deleted with all files on not containing a PDF file and no subdirectories and also not the currently running batch file as long as Windows does not prevent the deletion of the directory because of missing permissions or a sharing access violation.
Please note that the batch file does not delete other files in a directory which is not deleted as it can be seen also on the example.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
cd /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rd /?
setlocal /?

How to remove last segment in filepath in command prompt

I am working on a batch application where I have to get the current directory path via command prompt.
I can get the file location as:
C:\Users\Username\Downloads\Images\dance.png
or current directory as:
C:\Users\Username\Downloads\Images\stock_images\
I have to get the desired directory path as:
C:\Users\Username\Downloads\Images\
I have looked around on stackoverflow for the solution but could not find something useful.
So, how can I get parent directory of a file or subdirectory using batch script?
I've posted it a number of times, but can't locate it for the moment
#ECHO OFF
SETLOCAL
SET "name=C:\Users\Username\Downloads\Images\stock_images\dance.png"
FOR %%a IN ("%name%") DO FOR %%b IN ("%%~dpa.") DO ECHO Grandparent=%%~dpb&ECHO parent=%%~nxb

batch script to generate a list with file names newer than a saved date timestamp

I have a landing directory where we receive 10-15 files everyday. I then run a batch script to create a list with file names that have newly landed and then informatica reads the list of file names to process the new source files.
The problem here is, if a file is edited on same day after informatica loads the file. My batch script does not identify the updated file because the file has same date and name.
Is there a way to compare files based on timestamp and generate a file list? Any help will be greatly appreciated. Thanks!
The current batch script code:
rem this batch script is used to list all the files hosted newly to a xyz landing directory
set LandingDir=\\path\to\landing\directory\*.csv
set DateFile=%sys_var%\script\DateFile.txt
set LastRunDateFile=%sys_var%\scripts\LastRunDateFile.txt
set Temp_File_List=%sys_var%\scripts\Temp_File_List.txt
set File_List=%sys_var%\SrcFiles\File_List.txt
set /P _PreviousDate=<%DateFile%
type %DateFile% > %LastRunDateFile%
xcopy "%LandingDir%" /l /s /d:%_PreviousDate% .>%Temp_File_List%
type %Temp_File_List% | findstr /v File(s)>%File_List%
echo %date:~4,2%-%date:~7,2%-%date:~10,4% >%DateFile%
On Windows there is the archive attribute always set on a file automatically if a file is modified in any way.
Using the archive file attribute makes the task much easier than storing last modification files times of all files processed and comparing last modification file times on next run.
All needed to be done is removing archive attribute on file being already processed, i.e. added to the file list.
Example:
#echo off
setlocal
set "FilePattern=*.csv"
set "sys_var=C:\Temp\Test"
set "File_List=%sys_var%\SrcFiles\File_List.txt"
set "LandingDir=\\server\share\path\to\landing\directory"
if exist "%File_List%" del "%File_List%"
for /F "delims=" %%I in ('dir "%LandingDir%\%FilePattern%" /AA-D /B 2^>nul') do (
echo %LandingDir%\%%I>>"%File_List%"
%SystemRoot%\System32\attrib.exe -a "%LandingDir%\%%I"
)
if not exist "%File_List%" echo No new file!
endlocal
The command DIR returns because of /AA-D just files (not directories) with archive attribute set in bare format because of /B.
So output by DIR and processed by FOR are just the names of the files with archive attribute set without path and always without surrounding double quotes even if the file name contains a space or another special character.
The file names would be returned by DIR with full path on using additionally DIR option /S for listing recursively all files in specified directory and in all subdirectories matching the file pattern (and having archive attribute set).
Each file name is written into the file list file and then the archive attribute is removed from the file to ignore this file automatically on next run of the batch file except the archive attribute is set again because the file was modified in the meantime.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
attrib /?
del /?
dir /?
echo /?
endlocal /?
for /?
set /?
setlocal /?
See also the Microsoft article Using command redirection operators for an explanation of >> and 2>nul with escaping > with ^ to be interpreted on execution of DIR instead of FOR.

find path of current folder - cmd

I use this script to find out the current folder with its .bat file:
for /f %%i in ("%0") do set curpath=%%~dpi
echo %curpath%
it doesn't work correctly, if the path contains spaces(D:\Scripts\All Scripts -> retrieves only D:\Scripts\, if I place in the folder, whose path doesn't have spaces it retrieves the full path). How can I fix it?
2015-03-30: Edited - Missing information has been added
To retrieve the current directory you can use the dynamic %cd% variable that holds the current active directory
set "curpath=%cd%"
This generates a value with a ending backslash for the root directory, and without a backslash for the rest of directories. You can force and ending backslash for any directory with
for %%a in ("%cd%\") do set "curpath=%%~fa"
Or you can use another dynamic variable: %__CD__% that will return the current active directory with an ending backslash.
Also, remember the %cd% variable can have a value directly assigned. In this case, the value returned will not be the current directory, but the assigned value. You can prevent this with a reference to the current directory
for %%a in (".\") do set "curpath=%%~fa"
Up to windows XP, the %__CD__% variable has the same behaviour. It can be overwritten by the user, but at least from windows 7 (i can't test it on Vista), any change to the %__CD__% is allowed but when the variable is read, the changed value is ignored and the correct current active directory is retrieved (note: the changed value is still visible using the set command).
BUT all the previous codes will return the current active directory, not the directory where the batch file is stored.
set "curpath=%~dp0"
It will return the directory where the batch file is stored, with an ending backslash.
BUT this will fail if in the batch file the shift command has been used
shift
echo %~dp0
As the arguments to the batch file has been shifted, the %0 reference to the current batch file is lost.
To prevent this, you can retrieve the reference to the batch file before any shifting, or change the syntax to shift /1 to ensure the shift operation will start at the first argument, not affecting the reference to the batch file. If you can not use any of this options, you can retrieve the reference to the current batch file in a call to a subroutine
#echo off
setlocal enableextensions
rem Destroy batch file reference
shift
echo batch folder is "%~dp0"
rem Call the subroutine to get the batch folder
call :getBatchFolder batchFolder
echo batch folder is "%batchFolder%"
exit /b
:getBatchFolder returnVar
set "%~1=%~dp0" & exit /b
This approach can also be necessary if when invoked the batch file name is quoted and a full reference is not used (read here).
for /f "delims=" %%i in ("%0") do set "curpath=%%~dpi"
echo "%curpath%"
or
echo "%cd%"
The double quotes are needed if the path contains any & characters.
Use This Code
#echo off
:: Get the current directory
for /f "tokens=* delims=/" %%A in ('cd') do set CURRENT_DIR=%%A
echo CURRENT_DIR%%A
(echo this To confirm this code works fine)

batch script to set a variable with the current path location

How can I set a variable with the current location? For instance, if I get in c:\test and want to set the variable to test and if I get inside c:\test\test2 the variable will be set to test2.
I'm thinking about using a for to get inside a lot of folders and check if some file exists, if the correct file exist I want to set the current folder to a variable so I can copy the path and copy the folder.
The main problem deals with copying the rest of the files is the same folder as the .inf file.
The current directory is in the "shadow" variable cd.
You could try
set "var=%cd%"
%~dp0
This expands into the drive & path of the currently running batch file. I usually surround my batch files with something like:
#echo off
pushd %~dp0
...
popd
Edit: It seems I didn't understand the OP. My example gets the location of the currently running script, not the "Current Directory". +1 to jeb.
I think there is a little confussion here. %CD% always have the current directory, so you don't need to add anything to have it. However, by rereading your original question, I think that you need the LAST PART of the current directory, that is, the name of the current location excluding all previous locations. If so, then you may use this:
set i=0
:nextdir
set /a i+=1
for /f "tokens=%i% delims=\" %%a in ("%CD%") do if not "%%a" == "" set lastdir=%%a& goto nextdir
echo Current location: %lastdir%

Resources