Dir /b /s shows different results in a batch file and cmd.exe - batch-file

This is my first time here. I used the site to find answers to my questions anonymously many times before.
A very similar question already exists here, but it didn't help me with my problem.
In my batch file, I set a variable to pass to robocopy the files to exclude:
SET EXCL=*.bak *.inp_bak *.dwl *.err plot.log dotlog.txt logs\*.log
EDIT: I want to list and confirm all files to be excluded first.
The problem is in the last part, "logs\*.log", i.e. I am looking for .log files in a subfolder "logs" under the current folder.
In a command prompt window, I can execute this command without problems:
dir %EXCL% /b /s
and %ERRORLEVEL% returns 0. However, in my .bat I have this same line but %ERRORLEVEL% returns 1, and I noticed that DIR shows me all the files but when it gets to the "logs\*.log" part I get the message "File not found".
What I am trying to do is list any "plot.log" files in the current folder or any subfolder (/s) + all the .logs in the specified subfolder, but NOT other .log files in other subfolders.
Is it possible to do this on a single line within the batch file? I don't want to run two different DIRs

Related

How to get the current path of my batch file? [duplicate]

I have a batch file that I intend to distribute to our customers to run a software task.
We distribute them as a folder or .zip with the files inside. Inside, there is the batch files and another folder with the files needed to run the batch.
Normally, when you make a batch, you type the path where the files are. But I won't know where the files are. The files will still be kept inside the master folder, but I need to have the batch find that folder to run the files.
So for example: If they have the master folder on the desktop and they run it, it would need to be something like "C:\Users\Username\Desktop" to run. You would have the batch CD to that location.
But what if they run it from documents? I don't know the username, so I have to somehow have the batch find this. Any code and/or instructions would be great.
There is no need to know where the files are, because when you launch a bat file the working directory is the directory where it was launched (the "master folder"), so if you have this structure:
.\mydocuments\folder\mybat.bat
.\mydocuments\folder\subfolder\file.txt
And the user starts the "mybat.bat", the working directory is ".\mydocuments\folder", so you only need to write the subfolder name in your script:
#Echo OFF
REM Do anything with ".\Subfolder\File1.txt"
PUSHD ".\Subfolder"
Type "File1.txt"
Pause&Exit
Anyway, the working directory is stored in the "%CD%" variable, and the directory where the bat was launched is stored on the argument 0. Then if you want to know the working directory on any computer you can do:
#Echo OFF
Echo Launch dir: "%~dp0"
Echo Current dir: "%CD%"
Pause&Exit
ElektroStudios answer is a bit misleading.
"when you launch a bat file the working dir is the dir where it was launched"
This is true if the user clicks on the batch file in the explorer.
However, if the script is called from another script using the CALL command, the current working directory does not change.
Thus, inside your script, it is better to use %~dp0subfolder\file1.txt
Please also note that %~dp0 will end with a backslash when the current script is not in the current working directory.
Thus, if you need the directory name without a trailing backslash, you could use something like
call :GET_THIS_DIR
echo I am here: %THIS_DIR%
goto :EOF
:GET_THIS_DIR
pushd %~dp0
set THIS_DIR=%CD%
popd
goto :EOF
You can also do
Pushd "%~dp0"
Which also takes running from a unc path into consideration.
Try in yourbatch
set "batchisin=%~dp0"
which should set the variable to your batch's location.

Batch File to zip files - apply to sub directories

I'm looking to get a batch file to apply to all sub directories.
I have a number of folders. Each folder will contain file pairs
xxx1.mp3 and xxx1.cdg,
xxx2.mp3 and xxx2.cdg,
etc.
I have a 7zip batch file that will look for file pairs and create a single zip file xxx1.zip, xxx2.zip and delete the (now) redundant cdg/mp3 files.
However, this will only work if the bat file is run in each individual folder. What I'm really looking for is a switch to add to the bat file that if I run in the root directory, will run through all sub directories also.
The code I currently run is:
FOR %F IN (*.cdg) DO "C:\Program Files\7-Zip\7Z.exe" a "%~nF.zip" "%~nF.cdg" "%~nF.mp3" -sdel
Any help?
FOR /R %%F IN (*.cdg) DO IF EXIST "%%~dpnF.mp3" pushd "%%~dpF"&ECHO("C:\Program Files\7-Zip\7Z.exe" a "%%~nF.zip" "%%~nF.cdg" "%%~nF.mp3" -sdel&POPD
Note that this is a batch line - to execute from the prompt, reduce each %% in metavariable to % (but it's a whole lot easier to put it into a batch by cut-and-paste;saves all those typos...)
The required commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, delete the string ECHO( which appears before your command to actually execute the commands.
Using for /r will iterate through the filenames matching the supplied mask (it's possible to also add a starting directory - see for /?|more from the prompt.)
Since we know the selected full filename exists, first check that the paired file exists, then switch to the required directory, archive, and switch back.

How to delete files matching a certain pattern in their name?

I'm creating a batch file that deletes all Rar$DIa0.??? folders in the %TEMP% directory.
Is this possible, and how to do it?
The ??? is three randomized numbers. And that's where I have trouble with - deleting all folders that have Rar$DIa0. in the name.
for /d is designed for just this type of use. Something like this should work (remove one of the % if you're testing from the command line):
for /d %%i in ("%TEMP%\Rar$DIa0.???") do rd "%TEMP%\%%i"
The /d makes it work on directory names instead of file names.
If you want to make it easier on yourself, change to the %TEMP% folder first:
pushdir
cd /d %TEMP%
for /d %%i in ("Rar$DIa0.???") do rd "%%i"
The ??? makes it only act on folders that have three letters after a .. If your folders don't have just a three letter extension, change .??? to .*. If you've got a typo, and there is no actual . in the foldername, just remove it and use Rar$DIa0??? or Rar$DIa0*
You may want to test it first by changing rd to echo to make sure you get the folders you want before actually deleting them.
For more information about for (pun intended) type for /? from a command prompt.
The command line to use in a batch file for this task is:
#for /D %%I in ("%TEMP%\Rar$DIa0.*") do #rd /Q /S "%%I"
Command FOR with option /D searches in folder defined by environment variable TEMP for subfolders with folder name starting with Rar$DIa0. not having hidden or system attribute set.
The loop variable I holds for each found subfolder matching this folder pattern the name of found folder with full path without double quotes although the path to temp folder very often contains 1 or more spaces.
For that reason just the command RD with the parameters /Q for quiet execution and /S for deleting also all subfolders in the specified folder must be called with referencing the current value of loop variable I enclosed in double quotes.
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.
for /?
rd /?
By the way: WinRAR deletes the temporary folders usually automatically, except a file is opened from within an archive for viewing/modifying it in another application and WinRAR is closed before the other application is exited with the opened file. In this case WinRAR can't delete the temporary folder with temporarily extracted file because the file is still opened in another application. Of course also command RD can't delete the temporary folder if this folder is still the current directory of another application or a file in this folder is still opened by another application with a read/write access lock.

Batch File, search all files in folder, then sort

I've done some small batch files before, but never any that required file names being read in a folder.
I need a batch file that can sort a folder for me.
I need it to look into a folder, search each text file, if it contains a "string", then move it into an accepted folder, if not, move it into a rejected folder.
Any ideas how to tackle this?
I have used something as follows for finding text before.
find /c "string" file
if %errorlevel% equ 1 goto
I don't know how to make it search each file in a folder, and those file names change on a daily basis.
in your problem statement you said all of these files are .txt files. So I would recommend using a for loop to loop through each of the .txt files in the directory, and then use findstr to search for the intended string. The code I posted below will work in such a manner. Essentially it changes the directory to the desktop (or wherever your files are located), then loops through each .txt files and searches for the string. The findstr output is redirected to nul (for faster processing) and if this is successful, the .txt file is moved to C:\Users\Desktop\SuccessFolder, otherwise this file is placed in C:\Users\Desktop\FailureFolder. (Keep in mind the search "string", original location, and 2 folder locations still need to be set) I believe this code should work for what you are trying to accomplish. Let me know if any changes need to be made to the code =]
#Echo off
cd /D C:\Users\Desktop
FOR %%a in (*.txt) do (
findstr /C:"string" "%%a" >nul && move "%%a" "C:\Users\Desktop\SuccessFolder" || move "%%a" "C:\Users\Desktop\FailureFolder")

Batch File to Delete Specific Subfolders

I have three directories, and each of these directories contains 8 subdirectories, and each of those subdirectories contains 2 folders that I want to delete.
The structure:
[Edited the path-name]
C:/Process/CIM
/AB_CIM
/LOG
/DATA
/CC_CIM
/LOG
/DATA
/CIM_RD
...
...
C:/Process/DIM
/AB_DIM
/LOG
/DATA
/CC_DIM
/LOG
/DATA
/DIM_RD
...
...
C:/Process/RRS
...
So basically I want to remove LOG and DATA in all of those subdirectories. I thought of doing this using two separate batch files***:
The first batch file would contain:
call secondBatchFile.cmd CIM
call secondBatchFile.cmd DIM
call secondBatchFile.cmd RRS
Now, I'm not sure how to write the second batch file since those subdirectories have different names (but a common part: AB_*, CC_*, *_RD, etc). I was wondering if someone could help me with it.
Thanks for your help in advance.
*** The reason for doing this using two separate batch files is that I might sometimes need to keep LOG and DATA for one of the parent directories (e.g. CIM), so this way I can just comment out only one line of the first batch file and then run it.
You could do something like this if you're confident that LOG and DATA folders in other directories won't be picked up. Comment out the actual delete in the code below and review the .dat file output before executing.
REM Output all LOG and DATA sub-directories into corresponding DAT files
dir /ad/s/b log* > log_directories.dat
dir /ad/s/b data* > data_directories.dat
REM remove every entry listed in log_directories.dat
for /f %%i in (log_directories.dat) do rd/s %%i
REM remove every entry listed in data_directories.dat
for /f %%i in (data_directories.dat) do rd/s %%i
If you run this from C:, you're probably going to get directories you don't want. But assuming all of your targets are grouped under a dedicated sub-directory (and assuming you run the .bat from that dedicated directory), this won't be a problem.
And by default, this solution gives you your desired log of which directories it will be deleting (log will be overwritten for each run though).
If the 8 sub-folders are always the same pattern, i.e. AB_*, CC_*, *_RD, etc, the second batch file could be something like:
cd C:\%1%
rmdir AB_%1%\LOG
rmdir AB_%1%\DATA
rmdir CC_%1%\LOG
rmdir CC_%1%\DATA
rmdir %1%_RD\LOG
rmdir %1%_RD\DATA
...
cd c:\

Resources