Deleting all files and directories from desktop except .lnk - windows

Im trying to write a script for keep clear my desktop. I want to delete all files and directories except the shortcuts.I use Windows 10. My batch code is the following:
#echo off
COLOR 0E
cd "C:/Users/DA/Desktop"
FORFILES /S /C "if #ext!=lnk del /F /Q /S"
rd /S /Q "."
pause
exit
Maybe it is a dumb error, but Im a newbie in Windows command line. Thanks in advance.

There are several issues in your code:
You must precede the command line after the /C switch of forfiles with cmd /C, because you are using internal console commands (if, del). If you omit cmd /C, forfiles tries to find a program file named if, which does not exist.
There is no comparison operator != for the if statement. You mean not equal, so you need to state if not <expression1>==<expression2> instead.
The #ext variable expands to the file extension enclosed in quotation marks, so you need to state them around lnk also. Since the "" are in the quoted command line behind forfiles /C, you need to escape them like \" in order to establish literal " characters.
You forgot to specify what to delete at the del command.
The switches /S of forfiles and also del mean to process also items in sub-directories, but I assume you do not want that, because you want to clean up your Desktop directory.
There is the rd command, so I assume you want to remove any directories from the Desktop either. However, rd /S /Q "." tries to remove the entire Desktop directory (which will fail as your batch file changes to that directory by cd). I would put the rd command into the forfiles command line as well, because there is the possibility to check whether or not the currently iterated item is a file or a directory (forfiles features the #isdir variable for that purpose).
The cd command works only if you are running the batch file from the same drive where the Desktop directory is located (unless you provide the /D switch). I would go for the pushd command, which changes to the Desktop directory temporarily, until a popd command is there.
Instead of hard-coding the location of the Desktop directory, I would use the built-in environment variable %USERPROFILE%, which points to the user profile directory of the currently logged on user, where the Desktop directory is located in.
The exit command without the /B switch does not only end the batch file, it also terminates the command interpreter instance the batch file is running in. This does not matter when you run the batch file by double-clicking, but it does matter when you execute it within command prompt.
Here is the corrected and improved code:
#echo off
title Clean Up Desktop & rem // (this is the window title, just for fun)
color 0E
pushd "%USERPROFILE%\Desktop" || exit /B 1 & rem // (the command after `||` runs if `pushd` fails, when the dir. is not found)
rem /* Here you can see how to distinguish between files and directories;
rem files are deleted with `del`, directories are removed with `rd`.
rem The upper-case `ECHO`s are there for testing purposes only;
rem remove them as soon as you actually want to delete any items: */
forfiles /C "cmd /C if #isdir==FALSE (if /I not #ext==\"lnk\" ECHO del /F /Q #relpath) else ECHO rd /S /Q #relpath"
pause
popd & rem // (this restores the previous working directory)
exit /B & rem // (this quits the batch file only; not necessary at the end of the script)

You can try something like that :
#echo off
COLOR 0E
CD /D "%userprofile%\Desktop"
Rem To delete folders
for /f "delims=" %%a in ('Dir /b /AD ^| find /v "lnk"') do echo rd /S /Q "%%a"
pause
Rem To Delete files
for /f "delims=" %%a in ('Dir /b ^| find /v "lnk"') do echo del /F /Q /S "%%a"
pause
exit
NB: When your execution is OK, just get rid of echo command

You can use the for and if commands to accomplish this:
#echo off
COLOR 0E
cd C:/Users/DA/Desktop
for /d %x in (*) do #rd /s /q "%x"
for %i in (*) do if not %i == *.lnk del "%i"
pause
Pretty simple and works great.
Make sure that %i and %x are in "".

Related

How to delete *.bak files recursively older than a specific date depending on directory in file path?

I'm writing a batch file for Windows 7.
I currently have a code that deletes old backups from our masters folders within our site management folders. This is the code:
for /d %%A in ("Y:\*.*") do del /s /q /f "%%A\masters\*.bak"
However I need to code it to only delete things that are older than 3 years, which would be this code:
forfiles /P "Y:\" /S /D -1096 /M *.bak /C "cmd /C del #path"
However I need what is in the top code so that I can delete all *.bak files from the masters folders that exist within our 173 site management folders. I'm ripping my hair out figuring this out. I can't have it deleting *.bak files from our other folders.
I've tried combining the code, but below command line in batch file does not work as expected:
forfiles /S /D -1096 /M *.bak /C "cmd /C for /d %%A in ("Y:\*.*") do del /s /q /f "%%A\masters\*.bak"
How to delete all *.bak files older than 3 years anywhere in directory tree if second directory in file path is masters and keep all other *.bak files being newer or in a directory where second directory in file path is not masters?
Create first a batch file C:\Temp\DeleteBackup.bat with the following commands:
#echo off
set "BackupFileName=%~1"
if not "%BackupFileName:\masters\=%" == "%BackupFileName%" ECHO del "%BackupFileName%"
This batch code checks if the file name with full path and file extension contains anywhere \masters\ by removing this string case-insensitive from left argument of string comparison.
If the remaining string is not equal the unmodified file name string because of containing \masters\ in path, the IF condition is true and the backup file would be deleted if there would not be command ECHO which results in just displaying the DEL command line.
For example the complete list of backup files is:
Y:\masters\Level2\Level3\Level4\Level5\Test1.bak
Y:\Folder2\masters\Level3\Test2.bak
Y:\Folder3\Level2\masters\Level4\Test3.bak
Y:\Folder4\Level2\Level3\Level4\Level5\Test4.bak
Y:\Folder5\Level2\Test5.bak
Y:\Folder6\Level2\Level3\Level4\Level5\Level6\Test6.bak
Y:\Folder7\masters\Test7.bak
The files deleted would be:
Y:\masters\Level2\Level3\Level4\Level5\Test1.bak
Y:\Folder2\masters\Level3\Test2.bak
Y:\Folder3\Level2\masters\Level4\Test3.bak
Y:\Folder7\masters\Test7.bak
And the files remaining would be:
Y:\Folder4\Level2\Level3\Level4\Level5\Test4.bak
Y:\Folder5\Level2\Test5.bak
Y:\Folder6\Level2\Level3\Level4\Level5\Level6\Test6.bak
Then use in your batch file:
forfiles /P "Y:\" /S /D -1096 /M *.bak /C "C:\Temp\DeleteBackup.bat #PATH"
It is of course possible to modify DeleteBackup.bat to check if directory in second directory hierarchy level is masters.
#echo off
for /F "tokens=3 delims=\" %%I in ("%~1") do if /I "%%I" == "masters" ECHO del "%~1"
This code would delete from the complete list above the files:
Y:\Folder2\masters\Level3\Test2.bak
Y:\Folder7\masters\Test7.bak
And the files remaining would be:
Y:\masters\Level2\Level3\Level4\Level5\Test1.bak
Y:\Folder3\Level2\masters\Level4\Test3.bak
Y:\Folder4\Level2\Level3\Level4\Level5\Test4.bak
Y:\Folder5\Level2\Test5.bak
Y:\Folder6\Level2\Level3\Level4\Level5\Level6\Test6.bak
Robert Chizmadia Jr. asked in an already deleted comment:
Is it possible to use GOTO instead of calling another batch file on FORFILES command line?
The answer on this additional question:
FORFILES is not an internal command of cmd.exe like FOR. It is a console application stored in directory %SystemRoot%\System32 if used version of Windows has it pre-installed at all.
The command to execute as specified after FORFILES option /C must be an executable or script. That is the reason why cmd /C is always used when an internal command of Windows command interpreter cmd.exe like DEL should be executed by FORFILES whereby the really complete command would be %SystemRoot%\System32\cmd.exe /C.
So it is not possible to use a command like GOTO in FORFILES command as there is no executable or script with name GOTO.
Also GOTO in a FOR loop exits the loop and therefore interpreting of command lines of batch files continues on another position in batch file.
However, it is possible to use the same batch file for the file path evaluation and backup file deletion as used to run FORFILES command.
Example 1 with batch file not expecting any parameter for default operation:
#echo off
if not "%~1" == "" (
for /F "tokens=3 delims=\" %%I in ("%~1") do if /I "%%I" == "masters" ECHO del "%~1"
goto :EOF
)
%SystemRoot%\System32\forfiles.exe /P "Y:\" /S /D -1096 /M *.bak /C "%~f0 #PATH"
If this batch file is executed with an argument, it runs the FOR loop written to check if second directory in file path is masters and delete this file in this case after removing ECHO. Otherwise on starting the batch file without any parameter the batch file runs the FORFILES executable.
Example 2 with batch file expecting 1 or more parameters for default operation:
#echo off
if "%~1" == "#Delete:Backup#" (
for /F "tokens=3 delims=\" %%I in ("%~2") do if /I "%%I" == "masters" ECHO del "%~2"
goto :EOF
)
rem Other commands processing the parameters.
%SystemRoot%\System32\forfiles.exe /P "Y:\" /S /D -1096 /M *.bak /C "%~f0 #Delete:Backup# #PATH"
rem More commands executed after the deletion of the backup files.
This is nearly the same as example 1 with the difference that if first parameter used on running the batch file is case-sensitive the string #Delete:Backup#, the batch file expects as second parameter the name of a backup file with full path being deleted if second directory in file path is masters.
Like in all batch code examples the command ECHO must be removed before del command also in this code example to really execute the deletion of the backup files.
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.
echo /?
for /?
forfiles /?
goto /?
if /?
set /?

Windows Batch script - what does %%i mean?

I wrote (using knowledge from Internet) script (batch file) to remove all folders and files inside a folder.
DEL /F /Q /S C:\commonfiles\*
for /D %%i in ("C:\commonfiles\*") do RD /S /Q "%%i"
I just don't know what %%i means. Is it like i++ in C++?
%%i is simply the loop variable. This is explained in the documentation for the for command, which you can get by typing for /? at the command prompt.
The fact that a double percent sign is used in a batch file is discussed in these links:
What is the difference between % and %% in a cmd file?
https://superuser.com/questions/670992/what-does-the-percent-sign-and-in-a-batch-file-argument-mean
In this case FOR /D iterates trough all directories in C:\commonfiles\ and on each iteration the current directory is accessible with %%i variable. It's a special variable that is valid only in FOR command context. In command prompt you'll need to use:
for /D %i in ("C:\commonfiles\*") do RD /S /Q "%i"
For more info FOR /? or SS64.COM

How to recursive run DIR command without using /S switch

I have the following folders and files:
C:\Test\file.txt
C:\Test\Folder\file.txt
I am working on a Java program which looks for a specific folder and run DIR command on it. The folder is passed as a parameter and the results are saved in a file:
cmd /c dir "C:\Test" /s /b /a-D > c:\Test\DIR.txt
However, sometimes I do not have a folder as a parameter and I just have a file; my command will be:
cmd /c dir "C:\Test\file.txt" /s /b /a-D > c:\Test\DIR.txt
The results is:
C:\Test\file.txt
C:\Test\Folder\file.txt
When the parameter is a file, I just want that particular file to be listed (no recursivity). So, if I have:
cmd /c dir "C:\Test\file.txt" /s /b /a-D > c:\Test\DIR.txt
I want the result to be:
C:\Test\file.txt
How can I do this? Eliminating /S switch will work incorrectly if I have a folder as parameter.
Any suggestions are appreciated.
Option 1: Add a backslash to end and test if it is a valid folder:
cmd /c (if exist "somePath\" (dir "somePath" /s /b /a-d) else dir "somePath" /b /a-d) >c:\Test\DIR.txt
Option 2: Assume it is a file, suppressing error message, and conditionally do recursive DIR if first command failed:
cmd /c (dir /b /a-d "somePath" 2>nul || dir /b /a-d /s "somePath") >c:\Test\DIR.txt
Could you include a check in the Java code to see if the directory/folder exists before the call to cmd is made? I don't know Java syntax for that kind of thing, but in C# I'd use something like:
if (System.IO.Directory.Exists("C:\\Test"))
{
// start the cmd process with the folder you're after including the /S switch
}
else
{
// The directory won't exist if it's a file, so run it without the /S parameter
}
Of course, it depends on what how your program will work for if you can implement that kind of check or not. But it's an idea :)
IsDirectory.bat
#Echo off
pushd %1 >nul 2>&1
If errorlevel 0 if not errorlevel 1 Echo %~nx1 is a folder
If errorlevel 1 Echo %~nx1 is not a folder
Popd
If /i "%cmdcmdline:~0,6%"=="cmd /c" pause
pause

Delete all files in directory except in one subdirectory

I have this script:
forfiles /p "C:\Hello" /m *.* /s /d -5 /c "cmd /c if /i not #path==C:\Hello\Dontdelete del #file"
I'm trying to delete every file older than 5 days in C:\Hello except for files that are in C:\Hello\Dontdelete or any directory within this path.
Currently everything is getting deleted when I use the above script.
Thanks!
The fundamental problem is that #path is the full pathname - including the filename+extension, and quoted and #file is the filename+extension, also quoted. In consequence, the if statement as constructed can't be manipulated to work as anticipated.
Here's a way to get it working (I've made a few changes to suit my system which should be easy to manipulate to suit yours)
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
forfiles /p "%sourcedir%" /m *.* /s /d -6 /c "cmd /c call %cd%\selectdel #PATH"
GOTO :EOF
I set up selectdel as a batch in my current directory. No doubt it would be fine on the path, or simply forced as I have with the %cd%\.
selectdel.bat
#echo off
setlocal
if /i not "%~dp1"=="%sourcedir%\Dontdelete\" echo DEL %1
GOTO :eof
Obviously, I've simply echoed the del command - in case of accidents...
I do not know much about it, but I think you should make a lopping for every 5 days, the script did a check to see if there are files in the folder C :/ Hello, if yes, the script clears, if not, it does nothing. Search about it.

dos command to delete a folder except the named sub folders

Assume I have a directory in your computer under C:/dir1
And inside "dir1" we have more directories dir11, dir12, dir13,
And in each of the above directories we have more like below
dir11- dir111, dir112 dir113
dir1-dir121, dir122, dir123
dir13 - dir132,dir132,dir133
Now I need to find a command or a small script, which can delete everything under dir1 except couple of directories say dir122 and dir132.
Can you find something using DOS commands ?
You can use dir filespec /b >tmp.bat to list the file names in a text file called tmp.bat. Then edit that file to add del before each file name you want to delete. You can remove the file names you want to keep from the batch file and then do a "change all" to add del to each line. When it is edited properly, execute the batch file.
Alternatively, you could write a quick program under vb.net to do it.
Using the given examples: this should echo all the rd commands for the other folders.
#echo off
for /f "delims=" %%a in (' dir "c:\dir1" /b /s /ad ^| findstr /v /i "dir122 dir132" ') do echo rd /s /q "%%a"

Resources