Windows Cmd line delete command to delete all file except one - windows

I am looking for a single windows command where I need to delete all the files in a folder except one.
eg: Files listed under directory:
c:\users\admin\folder
abc
abcde.zip
abcdef
123.txt
Now, I want to delete all the files except "abcde.zip"
corresponding Linux command would be: rm -rf !(abcde.zip)
Is there anything like this on windows without using batch script, just a single line command?
Thanks in Advance!

Since Win's command interpreter doesn't have a rm -rf like command (that works on both files and dirs) we just need to modify the command that I placed in my 1st comment, actually split it in 2 commands (still in a single line: well, if the console is really really wide :) ), and execute them in a sequence (&):
one that takes care of the files (the /a:-d argument for dir), and launches del
one that takes care of the folders(the /a:d argument) and launches rmdir
Here's what it looks like (note that it does the job for the current directory):
(for /f "tokens=*" %f in ('dir /a:-d /b 2^>nul ^| findstr /v /b /e /c:"abcde.zip"') do (del /f "%f")) & (for /f "tokens=*" %f in ('dir /a:d /b ^| findstr /v /b /e /c:"abcde.zip"') do (rmdir /q /s "%f"))

Related

Windows Bat - The System Cannot Find the File Specified

I am using the following code in a .bat to cleanup a directory. It is to delete any directory with a time stamp older than 14 days. The thing is, this script works and deletes the appropriate directories. However it returns the error:
ERROR: The system cannot find the file specified I am unable to decipher the cause of this, and would like to get to the bottom of it.
FORFILES /S /D -14 /p %cd% /M "*" /C "cmd /c IF #isdir == TRUE rmdir #path /s /q"
As to the follow up question you asked:
Using a Windows batch file, find directories that do not contain any letters in their name. They can contain special characters and spaces. Delete the directories and their sub-folders w/o confirmation.
Put 1.bat in the directory you want to cleanup. Open a cmd window and run 1.bat.
Find all directories that do not contain any letters in their name and output their names to 1.txt. They can contain special characters and spaces.
Echo the directories to be removed. Do not remove them.
Remove comment tag to remove directories and sub-directories w/o confirmation.
1.bat
for /f "usebackq delims=|" %%a in ('DIR /b /ad ^| findstr /v /r "[a-Z]"') do echo "%cd%\%%a" will be removed without confirmation.
:: for /f "usebackq delims=|" %%a in ('DIR /b /ad ^| findstr /v /r "[a-Z]"') do rd /s /q "%cd%\%%a"

Why does execution in shell give different result that execution in batch script?

I'd like to list all .csv files in a directory and its subdirectories. It works nicely when I run this in the cmd terminal:
for /f %a in ('dir /b /s *.csv') do (echo %a)
When I put the same line of code into an (otherwise empty) text file (.cmd) and run that .cmd file, it outputs a blank line, but does not list any files.
Why does it make a difference whether I put the commands into a script or enter them directly (in one go) in the terminal?
Thinking it might be a delayed expansion issue, I also tried for /f %a in ('dir /b /s *.csv') do (echo !a!), but this doesn't list the files either.
Any ideas?
Double up the percent symbols in a batch file!
for /f %%a in ('dir /b /s *.csv') do (echo %%a)

Windows batch - match folders with a dot (.) in the folder name

I'm trying to figure out how to match folders with a dot in the file name (e.g., ".svn") in a Windows batch script.
Here's the basic script:
setlocal
pushd c:\myDir
#echo off
FOR /D /r %%G in ("*\.whatever") DO (
echo %%G
REM do stuff
)
#echo on
popd
endlocal
This works just fine for most folder names (e.g., "*bin"), but I can't figure out the method to specify a folder with the dot. "*.whatever" and "*\.whatever" return no results. I'm guessing I'm missing some escape character or something equally simple, but I haven't been able to find any documentation on it.
(Before anyone asks, no I'm not trying to recursively delete subversion folders; "*.svn" is just an example.)
Maybe I am missing something, but as you say it seems simple
for /r /d %%a in (.*) do echo %%~fa
But if the folders are hidden, the normal for will not be able to see them, so we need to execute a dir command an process its output with a for /f
for /f "delims=" %%a in ('dir /ad /s /b .*') do echo %%~fa

Exclusion of files of certain extension

In a Windows cmd batch script named my.bat, I want to execute a command for all the files in the current directory except for the batch file my.bat.
I use below command in my.bat currently to run the command only for *.txt *.ppt, but really as new files of different extensions might be added to the folder and hence execution of this command by excluding one type of file extension (in my case *.bat) would be more readable/helpful.
FOR /F "delims=|" %%i IN ('dir /b *.txt *.ppt') DO echo %%i
Question is: How do I exclude that file alone with that particular file extension and make the for command execute on all files of all extensions except the excluded one?
FOR /F "tokens=* delims=|" %%i IN ('dir /b *.*') do if not %%~xi==.bat echo %%i
I have added tokens=* in as well otherwise you won't get full filenames if they have spaces.
To echo without the dot
setlocal enabledelayedexpansion
FOR /F "tokens=* delims=|" %%i IN ('dir /b *.*') do (
set e=%%~xi
set e=!e:.=!
echo !e!
)
This is providing that the file doesn't have any other dots, otherwise it will remove them too. This is a bit more sturdy than just removing the 4th character from the end though, as not all files have a 3 character extension.
You could pass the output of the dir /b command through findstr, like so:
FOR /F "delims=|" %%i IN ('dir /b ^| findstr /v /r "^my.bat$"') DO echo %%i
The /v option to findstr prints anything that doesn't match the parameter. The match is based on a regular expression that matches only lines that contain my.bat and nothing else.

How to run *.exe /key from the .bat in loop

I have directory structure:
DIR
|-UNINSTALL.BAT
|-component_name
|-source
|-setup.exe
|-uninst.bat
|-another_component_name
|-source
|-setup.exe
|-uninst.bat
|-yet_another_component_name
|-source
|-setup.exe
|-uninst.bat
and so on...
In every directory like "component_name" I have setup.exe file which installs current component to the palette component in Delphi.
uninst.bat contains only this string:
"setup.exe" /uninstall
So I need to write UNINSTALL_ALL.bat in DIR that would run the uninst.bat in all component directories.
Thank you in advance.
you could do it with this line:
for /f %%a in ('dir /b /s uninst.bat') do call %%a
note that the '%%' is necessary for batch files. if you are testing this on the command line, only use one '%'
That is kind of akward in a batch file. Though you could probably do it with the foreach statement. I would suggest though that you have a look at Powershell which will definitely give you the power to do this simply and a whole lot more if you want it.
You want to use the "for" construct. Something like this:
for %%i in (component_name another_component_name yet_another_component_name) do %%i\uninst.bat
The double-escaping (%%) is necessary if you put the "for" loop in a batch file. If you are just typing it out in a command prompt, only use 1 %.
Also, you may be able to use a wildcard to match against the directory names, if they follow some convention. Open up a command prompt and run "for /?" to see everything it can do...I believe there is a /d option to match against directories. That would look something like:
for /D %%d in (component_*) do %%d\uninst.bat
(obviously, adjust the wildcard to match your component directories.)
This should work:
FOR /F %%a IN ('dir /b /s uninst.bat') DO START /B %%a
if you want them to wait each other, use this:
FOR /F %%a IN ('dir /b /s uninst.bat') DO START /B /WAIT %%a
The way you describe your problem, you have only one level of sub-directories and you always call the same batch, from the root. Therefore:
Uninstall_all.cmd
#echo off
for /F "delims=" %%d in ('dir /b /ad') do cd "%%d"& start /b /w ..\uninstall.bat& cd ..
Should do the trick.

Resources