I am trying to delete all directories with name SoftView Cache recursively in a certain location with the following Batch file:
set filename="SoftView Cache"
FOR /d /r "E:\Users\info\OneDrive - Les Entreprises Renouveau\Shared\Image\Plans" %%d IN (%filename%) DO rd /s /q "%%d"
pause
This simply returns "The system cannot find the file specified." I am able to see in the command line window that opens, it is searching for \"SoftView Cache" instead of \SoftView Cache as it should be. I understand that it is the space in the directory name that is causing the trouble. How do I correct the code to find and remove the directories named SoftView Cache?
Use command DIR to get folder list by pattern.
Used options:
/S - recursively;
/AD - only folders;
/B - full path output.
Use command FIND to avoid folders which contain leading spaces. Option /I ignores case.
Use command FOR /F to parse output and send folder's path to command RD as parameter
Batch-file code:
SET "filename=SoftView Cache"
FOR /F "DELIMS=*" %%d in ('DIR /S /B /AD "E:\blablabla\*%filename%" ^|FIND/i"\%filename%"') DO RD /S /Q "%%d"
Looks like Daemon-5 handled the syntax for the old batch command.
If interested in the PS equivalent, I believe this should do it... Best regards ~
Get-ChildItem -Path "E:\Users\info\OneDrive - Les Entreprises Renouveau\Shared\Image\Plans" -Include "SoftView Cache" -Directory -Recurse -Force | Remove-Item -Recurse -Force
Related
I have been trying to make this work for longer than I care to admit but for some reason I cannot figure it out. I usually work with Linux/Unix.
I simply want to search a directory for all instances where a filename matches a string.
Some things I have tried:
dir /s "/path/to/Test*"
dir /s/b "C:/path/to/Test*"
Additionally, I am hoping to return something that can easily be imported into an array. Something without unnecessary information. All I need Is the path or at the very least the filename for each file matched.
Edit: I dont want information like this (if possible)
Volume in drive C is OS
Volume Serial Number is...
Edit: Test* is intended to indicate all filenames beginning with Test. So TestA, TestB, & TestC should all match.
The same commands work on Linux, Mac, and Windows. http://github.com/PowerShell/PowerShell/
PS C:\src> (Get-ChildItem -Recurse -File -Path 'C:/src/d2' -Filter 'test*').FullName
C:\src\d2\test.bat
C:\src\d2\test.ps1
C:\src\d2\test.sql
C:\src\d2\test.txt
C:\src\d2\copyt\test.txt
Using command aliases, it can be shorter for interactive use. But, aliases are not a good practice for scripts.
PS C:\src> (ls -r -file 'C:/src/d2/test*').FullName
C:\src\d2\test.bat
C:\src\d2\test.ps1
C:\src\d2\test.sql
C:\src\d2\test.txt
C:\src\d2\copyt\test.txt
If you want an array, this will make one.
PS C:\src> $files = (ls -r -file 'C:/src/d2/test*').FullName
PS C:\src> $files.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Replace directory separators with -replace.
(Get-ChildItem -Recurse -Path 'C:/src/d2' -Filter 'test.*').FullName -replace '\\','/'
Join them to a single line with -join. This join uses a COMMA. Note that if the join uses a COLON in *NIX-style, it will not work well on Windows.
PS C:\src> (Get-ChildItem -Recurse -Path 'C:/src/d2' -Filter 'test.*').FullName -replace '\\','/' -join (',')
C:/src/d2/test.bat,C:/src/d2/test.ps1,C:/src/d2/test.sql,C:/src/d2/test.txt,C:/src/d2/copyt/test.txt
If you need a PATH-style separator, use:
(Get-ChildItem -Recurse -Path 'C:/src/d2' -Filter 'test.*').FullName -replace '\\','/' -join ([IO.Path]::PathSeparator)
I've just been searching for all files, called "test.*" all over my C:-drive, using this simple command:
dir /S C:\test*
Although I just mention the directory C:\, the /S makes sure all subfolders are used too. In top of that, there are no double quotes, as you can see.
Does this solve your issue?
Sorry, I didn't see that you're used working with UNIX/Linux, so here I have an approach you'll prefer:
forfiles /P C:\ /S /M test* /C "cmd /c echo #path"
This does the following:
/P C:\ Start looking in C:\
/S Search through subdirectories
/M test* Filename looks like "test*"
/C <cmd> When found, launch <cmd>
"cmd /c echo #path" Echo (write to output) the complete path of the found file or directory
This will give you a list of files and directories, written as full paths, something like:
"C:\Octave\Octave-5.2.0\mingw64\bin\test-libiberty.exe"
"C:\Octave\Octave-5.2.0\mingw64\bin\test-lua.exe"
"C:\Octave\Octave-5.2.0\mingw64\bin\test-tinyxml.exe"
"C:\Octave\Octave-5.2.0\mingw64\include\llvm\Testing" <-- this is a directory
"C:\Octave\Octave-5.2.0\mingw64\include\wx-3.0\wx\testing.h"
...
Which resembles a lot the typical UNIX/Linux results, you're used to.
More information about forfiles can be found, launching forfiles /?.
Based upon your statement, "I am hoping to return something that can easily be imported into an array", I'd assume you're probably looking for something more like this:
#Echo Off
Rem Ensure that extensions are enabled (required for SET and FOR commands)
SetLocal EnableExtensions
Rem Ensures that there are no existing variables in the environment with names beginning with file[
For /F "Delims==" %%G In ('" Set file[ 2> NUL "') Do Set "%%G="
Rem Gets every file matching the glob test* in the tree rooted at "C:\path\to"
Rem and defines an incremented variable name for each, beginning at %file[1]%
For /F "Tokens=1,* Delims=]" %%G In (
'" Dir /B /S /A-D "C:\path\to\test*" 2> NUL | "%__AppDir__%find.exe" /N /V "" "'
) Do Set "file%%G]=%%H"
Rem An example line to show you all of the variables you have now defined
Set file[ 2> NUL
Rem Pause the script to ensure that you have been able to read any output
Pause
Rem An example line to show you all the first defined variable value
Echo=%file[1]%
Rem Pause the script to ensure that you have been able to read any output
Pause
...and here it is without the Remarks:
#Echo Off
SetLocal EnableExtensions
For /F "Delims==" %%G In ('" Set file[ 2> NUL "') Do Set "%%G="
For /F "Tokens=1,* Delims=]" %%G In (
'" Dir /B /S /A-D "C:\path\to\test*" 2> NUL | "%__AppDir__%find.exe" /N /V "" "'
) Do Set "file%%G]=%%H"
Set file[ 2> NUL
Pause
Echo=%file[1]%
Pause
Don't forget to change C:\path\to\test* as required for your specific location and glob.
I have a folder with multiple subfolders under it. I would like to delete all test folders under the subfolders/example. How can I do this using windows batch script? Note that there is no test folder in some.
I know how to delete mainfolder/subfolder1/example/test. But am stuck with recursively deleting under each subfolder i.e delete mainfolder/*/example/test.
TIA
E.g:
mainfolder
subfolder1
source
example
test
subfolder2
source
example
test
subfolderX
source
example
for /r "c:\sourcedir" /d %a in (*) do if /i "%~nxa"=="test" echo rd /s /q "%a"
direct from the prompt - double each % to use as a batch line.
replace c:\sourcedir as appropriate
required rd is merely echoed to show what he script intends to do. Remove the echo keyword after testing to actually perform the deletion.
I recommend looking at ss64.com's CMD.EXE reference, specifically the DIR, FINDSTR, and FOR commands.
for /f %i in ('dir /s /a:d /b ^| findstr /i /e "example\test"') do rmdir /s %i
appears to be the appropriate command for what you have requested.
Notes on DIR: /S - Subdirectories, /A:D - directories only ("Attribute:Directory"), /B - "bare", no headers or footers, just the full pathname.
Notes on FINDSTR: /I - Case-insensitive, /E - Match at end-of-string
Verbose descriptive summary of command: Create a list of directories, including all subdirectories, and select only those that end in "example\test", then remove each of them, including all files and subdirectories in them.
for /R "mainfolder" /D %%a in (example\te?t) do rd /S "%a"
The only inconvenient of this method is that the name of the target folder must be given as a wild-card, so you must give a name that does not include any other undesired folder. If the name is given with no wild-card, the for command may include other folders.
You just need to iterate through the main directories, and check for the existence of the directory that you want to delete:
for /D %%d in (mainfolder\*) do if exist "%%d\example\test" rd /s /q "%%d\example\test"
My current folder structure goes as follows:
E:\Videos\Movies\Random Folder Name\Subs\Random File Name.srt
I would like to move my .srt files up one level so it reads:
E:\Videos\Movies\Random Folder Name\Random File Name.srt
I would prefer this to be a .bat file, but am willing to use PowerShell.
~EDIT~
I found something online that partially works and edited it to my needs:
#echo off
set thisdir=%cd%
for /f "delims=" %%A in ('dir /b /ad') do (
cd /d "%%~dpnA"
for /f "delims=" %%B in ('dir /b /ad') do (
echo Level 2 Directory: %%~dpnB
cd /d "%%~dpnB"
for /f "delims=" %%C in ('dir /b /ad') do (
echo Level 3 Directory: %%~dpnC
cd /d "%%~dpnC"
move *.srt ..\
cd..
rd "%%~dpnC"
)
)
)
This works, but only for the first folder, I can't seem to make Level 2 recursive as that is the level with random movie names. I tried replace for /f with for /r, but it was a no go.
Here's a one-liner:
forfiles /m *.srt /s /c "cmd /c move #file .."
Full code (you can run this from any drive now):
#echo off
cd /d E:\Videos\Movies\
for /r %%i in (*.srt) do move "%%~dpnxi" "%%~dpi.."
pause
This looks for all files with type .srt and moves them to the folder it was found in -1 directory (%%~dpi is the directory it was found in, adding .. to a path removes the last directory, so C:\Users\.. would put you at C:\).
PS: This time I have tested this, and it works.
Although the answers already given work, I still wanted to try and figure out how to perfect the code to my exact needs. Couldn't accomplish this with CMD, so I looked into powershell (which was easier for me to grasp for some reason) and coded this:
$sourcefolder = "F:\Videos\Movies\*\Subs\"
$files = Get-ChildItem -Recurse $sourcefolder | where {$_.PSIScontainer -eq $false}
foreach ($file in $files)
{
$destinationFolder = Split-Path -Parent $file.Directory.FullName
move-item $file.FullName $destinationFolder
}
It doesn't specify .srt files, but they are the only extension located in that folder. Thank you for the help guys!
I have the directory structure /foo/bar/fooBar/.. . I want to write a Windows command where I can mention the path till foo directory and it deletes all the files and directory recursively in /foo, but it should NOT delete the foo directory.
I have been using rmdir /q /s [path to foo] but this command deletes the foo directory as well. Let me know if there is any command(s) to accomplish this.
rd /s /q /path/to/foo
md /path/to/foo
del /f /s /q DirectoryWhichContainsFilesToDelete/\*
This will delete all files in the folder DirectoryWhichContainsFilesToDelete without deleting the folder itself.
Have fun :)
I had been scratching my head on this one as well. It is easy enough to create a for loop that uses rmdir however it leaves behind folders that have spaces in the long names. It is possible to manipulate a dir list and get the 8.3 filenames however here is a much simpler solution.
Create an empty folder then;
robocopy \empty_folder \folder_with_sub_folders /PURGE
All subfolders & files will be deleted.
del X /f /s /q
rd X /s /q
this WILL remove the ROOt directory though. make it again with
md X
or make a copy of it first.
otherwise you'll have to do batch funkiness
dir X /ad /b
will give you a list of the immediate subdirectories of X. you can work out the rest
I was looking for a simple command to delete all files in a directory recursively but leaving the directory structure unchanged. So, maybe this could be interesting ;)
for /f "delims=" %i in ('dir /B /S /A:-DH') do #del /F /Q /A:H "%i"
The command 'dir /B /S /A:-D' lists only files (/A:-D) in current directory recursively (/S) without 'dir' summary report (/B). The 'for' loops through each full line (/delims=) and executes the delete command, forced and quiet. I additionally used the hidden flag (/H) both for listing and deletion for some mysterious (e.g. thumbs.db) files.
deltree /foo/* should work fine.
I have used this in a batch file in the past. It uses a for loop to navigate the directory structure.
Here I remove the cvs sub directories off of a tree, needed when copying from one branch to another.
#echo off
if /I exist CVS. rd CVS /s /q >nul
for /F %%z in ('dir cvs /ad /s /b') do echo %%z && rd /s /q %%z
echo Batchfile %0 is complete
Try to use Powershell:
powershell -Command "Remove-Item '\foo\*' -Recurse -Force"
To prevent deleting of the foo directory try change directory to foo prior to the delete such as:
cd c:\foo
rd /s /q c:\foo
This will delete all the files and folders under foo but NOT foo. An error message will be displayed as follow "The process cannot access the file because it is being used by another process."
I just want to know how can I get all the names of the folders in a current directory. For example in my current directory I have three folders:
stackoverflow
reddit
codinghorror
Then when I execute my batch script all the three folders will print in the screen.
How can I achieve this?
Using batch files:
for /d %%d in (*.*) do echo %%d
If you want to test that on the command line, use only one % sign in both cases.
On Windows, you can use:
dir /ad /b
/ad will get you the directories only
/b will present it in 'bare' format
EDIT (reply to comment):
If you want to iterate over these directories and do something with them, use a for command:
for /F "delims=" %%a in ('dir /ad /b') do (
echo %%a
)
note the double % - this is for use in a batch, if you use for on the command line, use a single %.
added the resetting of default space delims in response to #Helen's comment
With PowerShell:
gci | ? { $_.PSIsContainer }
Old Answer:
With PowerShell:
gci | ? {$_.Length -eq $null } | % { $_.Name }
You can use the result as an array in a script, and then foreach trough it, or whatever you want to do...
For getting all the subfolders of a specific directory and display it in CMD :
#echo off
dir C:\input /s /b /o:n /a:d
Pause&Exit
For getting all the subfolders of a specific directory and save it in a text file :
dir C:\your_directory /s /b /o:n /a:d > output.txt