I have a directory which has subdirectories like this:
C:\FILES
C:\FILES\DONE
I want to check that FILES contains no files:
if not exist C:\FILES\*.* (
echo No files to process.
exit /b
)
But the test "not exist ..." is never true because of the subdirectory.
Any ideas on how to check if the directory has any files that are not directories?
Try to get the list of files and if it fails, there are no files
dir /a-d "c:\files\*" >nul 2>nul || (
echo No files to process
exit /b
)
If there are no files, the dir /a-d command (the switch means exclude directories) will fail. || is a conditional execution operator that will execute the following commands if the previous one has failed.
Only when there are files, the for execute the goto.
for %%a in (C:\FILES\*.*) do goto files
echo No files to process.
exit /b
Simple code:
for /f "delims=|" %%f in ('dir /b c:\FILES\') do goto :files
echo No files found
pause
goto:eof
:files
echo Files found
pause
goto:eof
If you want to check if exists sub-directories on this level:
(DIR /D "C:\FILES\" | findstr /i /p /r /c:"2 Directory" > nul 2> nul) && echo "No directories except current and parent."
This simple inline command could be easy adapted for any situation ;-)
Try
if not exist dir c:\FILES\*.* /a:-d (
You can find more on dir here
PS
I do not have DOS at my reach. So I can't test the above code snippet. But I think it is close to what you are looking for.If not something very close to that should work.
Related
I am trying to write a simple tool to delete junk Mac files from a Windows system, however, I am having trouble as a specified folder (.fseventsd) remains, no mater what I do. Below is the batch file, and the specific area of concern is the rmdir command in the :.fseventsd section.
rem #echo off
cls
cd \
:.fseventsd
echo Searching for '.fseventsd' folders.
rmdir /S /Q ".fseventsd" 2> nul
if errorlevel 1 echo No '.fseventsd' folders were found.
goto :.DS_STORE
if errorlevel 0 echo All '.fseventsd' folders have been deleted.
:.DS_STORE
echo.
echo Searching for '.DS_STORE' files.
del /s /q /f /a:rash .DS_STORE 2> nul
if errorlevel 1 echo No '.DS_STORE' files were found.
goto ._.*
if errorlevel 0 echo All '.DS_STORE' files have been deleted.
:._.*
echo.
echo Searching for '._.*' files.
del /s /q /f /a:rash ._.* 2> nul
if errorlevel 1 echo No '._.*' files were found.
goto END
if errorlevel 0 echo All '._.*' files have been deleted.
echo.
:END
echo All tasks have now been finished.
pause
Any help would be greatly appreciated.
You need to use a for /r loop which loops through subfolders just like this:
for /R "C:\path\you\want" %%A IN (.) do (
if "%%A"=="Foldernameyouwant" rd Foldernameyouwant
You can make any minor changes you want to the code provided.
Hope this helps!
The path to the folder and the format come to the input of the batch file
file(for example, txt) (as parameters of a batch file).
The folder must contain different files.
If such folder does not exist, then write “This folder does not exist” and
terminate the program.
If such a folder exists, then find everything in it and in its subfolders
files of the specified extension for which it is installed
archive attribute. Output the number of such files in
console
[Edit /]
This is what I have:
#echo off
if not exist %1 (echo "This folder does not exist" && pause && exit /B )
set /a count=0
for %%i in (dir %1\*.%2 /A:A /S ) do ( set /a count+=1 )
Echo in the folder %1, found %count% files with extension %2 and attribute
Archive
pause
The final count is incorrect
This in a batch file works for me. One problem is that without the /B option, it is also counting extra records coming back for directories. Your current "for" is actually counting the parts of the statement inside it, not the actual output in running the command.
#echo off
cls
SETLOCAL EnableDelayedExpansion
if not exist %1 (echo "This folder does not exist" && pause && exit /B )
set /a count=0
for /f "tokens=*" %%G in ('dir "%1\*.%2" /A:A /S /B') do (
set /a count+=1
)
Echo in the folder %1, found %count% files with extension %2 and attribute Archive
pause
Your line for %%i in (dir %1\*.%2 /A:A /S ) do ... is wrong in a few ways.
You want to process the output of a command: add /f and single-quoting the command.
You count every line of the output (including header and summary: add /b to list just the filenames.
if there are spaces in your parameters, it will fail: use %~n to remove any surrounding quotes and quote the full path.
So allthogether, the line should probably be:
for /f %%i in ('dir /b "%~1\*.%~2" /A:A /S') do ...
See for /? and dir /? for details.
(to be exact, you should also add "delims=" to get the whole filename instead of just its first word, but as you are just counting the lines, it wouldn't change anything)
Another thing: if not exist %1 (echo "This folder does not exist" is suboptimal. If no parameter was given, %1 is empty, the if results in if not exist (echo (tries to find a file named (echo and the command to be executed would be "This folder does not exist" which results in the error message '"This folder does not exist"' is not recognized as an internal or external command, operable program or batch file.
Safer Syntax: if not exist "%~1" (echo ...
I am a CMD newbie and have a question with a batch script I am working on.
I have a parent directory with 30 sub-directories containing .pdf files, and I need a filelist.txt for each sub-directory, and have each filelist.txt save as the file name of the sub-directory it belongs too. This has been completed with the script below:
#echo off
cd /d "C:\Desktop\parentDir"
for /d %%a in (*) do (
DIR /B /ON /A-D "%%a" > %%a.txt.
move %%a.txt "%%a" >nul
)
My question is how, can I remove file extensions in the output of each filelist.txt. For ex. when I run the script now, the output .txt file shows 1111.pdf
1112.pdf
I need the ".pdf" removed
I know with a "for" command you can "do" echo %%~na to remove file extensions, but I have no clue how/where to factor this into the current script.
Any help is appreciated!
You are using DIR command to list all files. It does not have a switch to hide extension.
You can replace the DIR command with a FOR loop, like you pointed out.
cd /d "C:\Desktop\parentDir"
for /d %%a in (*) do (
for %%f in ("%%a\*") do #echo %%~nf >> %%a.txt.
move %%a.txt "%%a" >nul
)
I know this is dumb question but due to lack of my DOS knowledge i have facing trouble. I have a dir which have more than 98000 subdirs but many of them dont have any files i just want to list them with path
for now i am using this batch file
#echo off
for /d /r %1 %%A in (.) do (
dir /a /b "%%~fA" 2>nul | findstr "^" >nul || echo %%~fA
)
this is exactly does what i just want but the problem its not saving the list to a text file as lots of lots of dirs are empty cant copy from the cmd i tried with this code just modifying
#echo off
for /d /r %1 %%A in (.) do (
dir /a /b "%%~fA" 2>nul | findstr "^" >nul || echo %%~fA >epty.txt
)
but its just save one line not a list. what i want need just all list to be printed to a text file of this function.
Thanks again for your help
You could try redirecting the whole output from this script to a text file when you call it. E.g. if the first script you gave was saved to a file named script.cmd in your current working directory then you could call it from the command prompt using:
script.cmd > output.txt
i have the following code in batch (cmd):
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if %errorlevel%==1 (
command
SKIP
)
command
)
EDIT:
To make things more clear:
for /f... searches for a directory called 'Example' and loops to search for more directories than one.
the first command is a delete command, it deletes all files in the directory.
the command that happens when an error occurs, is a echo command which writes some info about the error to a text file.
now the hole skip thing; sometimes, the files can't be deleted because of access denied or this file is in use by.... Normally, what would happen if there weren't a skip thing, it would just stop the command and hang. So, what i want to do, is prevent this from happening. Alternatively, i want to use something like skip, so it can skip the file and continue anyways. So i think this command needs to be piped in the delete command.
I hope it's clear now.
Thanks in advance.
Like this?
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if not errorlevel 1 (
command-for-success
) else (
command-for-error
)
)
Create the two command files and run delex.cmd. The files and directories that are not deleted will be logged to delex.txt. The ones that hang, will have a minimized cmd window open that gets killed after a delay by using ping (thanks to Doc Brown's suggestion).
delex2.cmd
----------
#echo off
del /q %1
if exist %1 echo %1 not deleted!>>delex.txt
exit
delex.cmd
---------
#echo off
if exist delex.txt del delex.txt
for /f "delims=" %%f in ('dir /s /b example') do start "delextaskkill" /min delex2.cmd "%%f"
ping 127.0.0.1 -n 3 -w 1000> nul
taskkill /fi "Windowtitle eq delextaskkill"> nul
Tested with:
\example
| file1
| file2
| file3
| file4
| file5
|
\---example
file1
file2
file3
file4
file5
When one uses del, and "access denied" or "this file is in use by..." occurs, %errorlevel% is 0, so testing %errolevel% is useless. Perhaps the following simple solution works in your case:
for /f "delims=" %%f in ('dir /b /s Example') do (
del %%f
if exist %%f (
echo "file not deleted"
) else (
echo "file deleted"
)
)
I believe that this is what you want
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if not errorlevel 1 (
command
) else (
command
goto :eof
)
)
Perhaps this is more advanced than can be accomplished using just built-in cmd processing. Why not consider using the Windows Scripting Host (vbscript/jscript) or even PowerShell? Both will likely provide you the level of control you are requesting.
Try this batch file:
#echo off
REM For each directory named 'Example' ...
for /f "delims=" %%f in ('dir /b /s Example') do (
REM .. enter the directory and delete all the files found there.
pushd .
cd %%f
del /q *
for /f "delims=" %%z in ('dir /b') do (
REM Any files that still exist must have been inaccessable. Log an error.
echo Unable to delete file %%z > C:\logfile.txt
)
popd
)
Tested with the following directory structure:
folder\
|------Example\
| |-------file1 (write-protected)
| |-------file2
| |-------file3
|------deeper\
|-------Example\
|-------file4
|-------file5 (write-protected)
|-------file6
After running the batch file, only file1 and file5 were left. An "Access is denied" message was printed for each write-protected file encountered; if that gets annoying you re-direct the output of the batch file like script.bat > NUL to hide it.
So after all the existing answers didn't satisfy you and you absolutely need a skip within your batch file, i will make another try:
#echo off
setlocal
for /f "delims=" %%f in ('dir /b /s batch') do call :DoSomething %%f
goto end
:DoSomething
echo Here i am: %1
if %errorlevel%==1 goto :eof
echo No error occured
goto :eof
:end
endlocal
The trick is, that the for loop calls a sub function within the same file and gives the needed parameter to it. This new call runs in a new context and can only access the variables which are defined after the do call :DoSomething in the given order their.
So you have to access the variables here with %1, %2, etc. If you want to leave this context you have to make a goto :eof to jump to the end of the file (this marker is predefined in batch mode and should not occur within your file), what leaves the context and returns to the for loop.
After running through the whole loop we just jump to the :end marker, make a little clean up and are finished.
The following looks for the file extentions you want recursively under the "dirname" directory tree and executes commandstuff.bat against that file name:
for /r %i in (c:\dirname\*.ext) do
commandstuff "%i"
Commandstuff.bat looks like this:
#ECHO OFF del %1 IF (%ERRORLEVEL% ==
0) goto END
:ERROR Echo Error deleting %1
:END Echo end
This would run commandstuff.bat for you to delete the files you want. When there is an error it will simply echo the file details and continue processing the next file.