Dear StackOverflow community,
Could you please advise me with a Batch code for the following scenario:
To find the folders named "Autoname" if they exist, and delete their
host folders (X), folder itself (Autoname) and all the files inside.
(X ) folders may have any names
The path is: %userprofile%\AppData\Local\ -X- \ "Autoname" \
folders & files.
I found similar post and similar post but it's not what I need.
Thank you All for your time, I especially appreciate the answer from #Compo, it is accepted as the best!
Your question now suggests that the Autoname directories exist any level within your temporary directory.
The following examples should be all that's required:
From a batch file:
#Echo Off
For /F "Delims=" %%A In ('"Dir/B/S/AD-L "%Temp%"|FindStr/IEC:"\\AutoName""'
) Do If Exist "%%~dpA" RD/S/Q "%%~dpA"
From the Command prompt:
#For /F "Delims=" %A In ('"Dir/B/S/AD-L "%Temp%"|FindStr/IEC:"\\AutoName""') Do #If Exist "%~dpA" RD/S/Q "%~dpA"
for /f "delims=" %i in ('dir /b /s /ad u:\sourcedir\*') do #if /i "%~nxi"=="e9" ECHO rd /s/q "%~dpi."
This should delete the parent of any subdirectory of the u:\sourcedir directory which itself contains a subdirectory e9. The directory names aren't magic - just what I used for testing.
Removal of the parent directory will delete all files and directories under the deleted directory.
This code will simply REPORT what it intends to do. Once verified you will need to remove the echo keyword to perform the deletion. Note that it's possible for this script line (it's intended to be invoked directly from the prompt) to generate error messages should it attempt to delete an e9 directory that existed below a directory its already deleted. Appending 2>nul to the line (including the leading space) should suppress reporting of such errors.
If you would like to move ahead into PowerShell, the following might work. When you are confident that the correct directories will be deleted, remove the -WhatIf from the Remove-Item cmdlet.
Get-ChildItem -Recurse -Directory -Filter 'Autoname' |
ForEach-Object { Remove-Item -Path $_.PSParentPath -Recurse -WhatIf }
Related
I would like to write a script that searches through a folder and deletes any raw files (.nef) that don't have a matching jpg. For example,
Folder structure:
DSC_0001.nef
DSC_0001.jpg
DSC_0002.nef
DSC_0003.nef
The program would delete DSC_0002.nef and DSC_0003.nef.
How can I do this?
FOR /R %%F IN (*.NEF) DO #IF NOT EXIST "%%~dpnF.jpg" DEL "%%F"
Note: the /R switch means recursive (i.e. it will continue to run this command throughout the entire directory tree from the directory where it is run from). Omit that switch if you don't want to process subdirectories as well.
A possible PowerShell solution:
Get-ChildItem -Path "C:\temp\nef" -Filter "*.nef" | foreach {
if( -not (Get-Item $_.FullName.Replace('.nef','.jpg') -ErrorAction SilentlyContinue)){
$_ | Remove-Item -WhatIf
}
}
Remove the -WhatIf to actually make it delete the files.
You will need to use (for a single folder):
#echo off
cd to\folder
for %%A IN (*.nef) do (
if not exist %%~nA.jpg (del %%~fA)
)
And for multiple folders, use:
#echo off
for /R "full_path_to_parent_folder" %%A IN (*.nef) do (
if not exist %%~dpnA.jpg (del %%~fA)
)
So i'm currently trying to delete a bunch of subfolders that were created by a program, on a recurring basis because it will recreate the subfolders. I know how to schedule the batch file, right now my issue is how to efficiently create the batch file to begin with. To clarify, say i have a directory named D:\IGSG. There are 250 folders within D:\IGSG, and within each one of those is a folder named D:\IGSG\F252341\arg. I want to delete all of the \arg folders, from all ~250 F folders I have, without deleting the other files inside the F folders. Right now the only way to do it that I know of would be to have a batch that goes
cd D:\IGSG\F252341
del /Q arg
and to repeat those lines for every subfolder, but typing out those folder names for every folder in there would be tedious, especially considering new ones are created from time to time. So i'm looking for a way with a batch to delete the subfolder of a subfolder, without deleting other files, if that makes sense.
On the cmd line for /d /r X:\path in combination with a wildcard will enumerate all folders names arg the appended .? meets this requirement:
for /d /r D:\IGSG %A in (arg.?) do #echo rd /s /q "%A"
if the output looks right remove the echo.
In a batch file double the %-signs -> %%A
#Echo off
for /d /r D:\IGSG %%A in (arg.?) do echo rd /s /q "%%A"
One of the rare cases where batch/cmd line can compete with PowerShell.
This PowerShell script will recurse through the subdirectory structure and delete all files and subdirectories inside arg directories. Be sure to change the location of the IGSG directory to yours. When you are satisfied that the correct files will be deleted, remove the -WhatIf from the Remove-Item cmdlet.
Get-ChildItem -Directory -Recurse -Path 'C:\src\t\delsubs\IGSG\F*' -Filter 'arg' |
Remove-Item -Path {(Join-Path -Path $_.FullName -ChildPath '*')} -Recurse -Force -WhatIf
If you need to run it from a cmd.exe shell, put the code above into a file named 'dodel.ps1' and run using:
powershell -NoProfile -File .\dodel.ps1
I am trying to delete file from a folder which has 3,500 + files.
FolderA(3,500+Files), FolderB(<260 Files).
What I want is that I want a FolderA(3,500+Files) - FolderA(list.txt) = Missing files.
I have tried :
Get-Content c:\path\to\list.txt | Remove-Item
It doesn't work.
FolderA has over 3,500 files and within the folder i have a file called "list.txt" which has list of all files which I would like to delete from FolderA
Hope this make sense.
Thanks,
Yogs
cd "C:\Users\gggggg\Desktop\missing2"
Get-Content "C:\Users\XXXXX\Desktop\missing2\ToBeDeleted.txt" | Remove-Item
Change active folder to the folder to be processed, get the list and remove each item
For a batch solution
for /f "delims=" %%a in ("C:\Users\XXXXX\Desktop\missing2\ToBeDeleted.txt") do (
del "C:\Users\gggggg\Desktop\missing2\%%a"
)
dir /b /a-d "FolderA*"|findstr /g:"FolderA\list.txt"
should do what you appear to want.
What has "FolderB" go to do with the problem?
--- er, you want to delete files that are not in the list list.txt ?
Well, the above should give you a list of files-to-be-deleted, so
for /f "delims=" %%a in ('dir /b /a-d "FolderA*"^|findstr /g:"FolderA\list.txt"') do ECHO(del "FolderA\%%a"
should echo the same list. If it is correct, change the echo(delto del after verification to actually delete the files.
I am attempting to create a batch file to copy several files listed in a text file to a new folder. I have found several threads relating to this, but I can still not get the batch to work properly. The problem I am encountering is that the files listed in the txt are all in different source locations and have different extensions. The list reads, for example:
C:\Users\Foo\Pictures\Photographs\September\P1030944.jpg
C:\Users\Foo\Videos\Art\Movies\Class\movie.avi
C:\Users\Foo\Music\Jazz\20051.mp3
...etc
All the copy commands I could find have to list either the source directory i.e.
set src_folder=c:\whatever\
set dst_folder=c:\foo
for /f %%i in (File-list.txt) DO xcopy /S/E/U "%src_folder%\%%i" "%dst_folder%"
or the extension i.e.
for /R c:\source %f in (*.xml) do copy "%f" x:\destination\
but I need it to gather that information from the list itself.
If it helps I know that there are only files of a possible 39 different specific extensions in the txt (*.jpg *.gif *.png ... *.xhtml *.xht)
Any help/ideas?
Start reading HELP FOR and then try the following at the command prompt
FOR /F %a in (input.txt) DO #ECHO COPY %a c:\newfolder\%~nxa
you can see that %a gets expanded to the actual line in the input file, and that %~nxa is a way to extract the name and the extension from the file.
After careful testing, move the command to your BAT file, replace %a to%%a, and remove the ECHO command
#echo off
SET destfolder=c:\newfolder
FOR /F "delims=" %%a IN (input.txt) DO COPY "%%a" "%destfolder%\%%~nxa"
notice the wraping of the names with quotes "; and the inclusion of the "delims=" option; both are needed in case filenames contain blanks.
Finally be careful with possible name duplicates in the destination folder. If that is possible, you need to find an strategy to cope with such collisions. But this can be the subject of another SO question, can't it?
One sample which worked for me...
Replace my directories C:\whatever and C:\temp\svn with yours...
assuming that your filelist is named antidump_list.txt and located under C:\temp\svn\
> set src_folder=C:\whatever
> set dst_folder=C:\temp\svn
> for /f %%i in (C:\temp\svn\antidump_list.txt) DO copy "%src_folder%\%%i" "%dst_folder%\%%i"
Regards,
Gottfried
I have found that the easiest way to do this is to use a powershell script.
$Files = Get-Content File-list.txt
$Dest = "C:\output"
foreach ($File in $Files) {
Copy-Item $File $Dest
}
If you need to run it from a batch file, paste the above script to file named CopyFiles.ps1 and add the following command to your batch file
powershell -executionpolicy bypass -file .\CopyFiles.ps1
Since, powershell is included by default on Windows7 and newer, this method is as easy as doing the same with batch commands only.
Here is some code I made :)
#echo off
set source="R:\Contracts\"
set destination="R:\Contracts\Sites\"
ROBOCOPY %source% %destination% *.srt *.pdf *.mp4 *.jpg /COPYALL /R:0 /S
for /r %source in (*) do #copy "%destination" .
R:\Contracts\ is full of folders which have files in them.
I want to copy all to R:\Contracts\Sites\ and flatten the folder structure.
Everything copies well but also the folder structure.
Thank you
You could do that with a PowerShell one liner.
In this example I filter out all the files with the .txt extension from all the subfolders. And then send them to the Copy-Item Cmdlet.
Combine the Cmdlets Get-Childitem (GCI for short), -recurse, and -filter and then pipe the result to the Copy-Item Cmdlet. Use -WhatIf first to check that the output is what you expected.
Copy to another folder (Use -WhatIf and verify the output to check your command before committing to copying the files):
Get-Childitem -recurse R:\Contracts -filter *.txt | Copy-Item -Destination R:\Contracts\Sites -WhatIf
To do multiple filetypes as you've asked, you can just run multiple commands, one for each filetype.
No single command will flatten the hierarchy for you; you will have to use multiple commands. It can be done simply by using FOR /R to walk the hierarchy, coupled with your copy/move command of choice (move, copy, xcopy, robocopy). Because your destination is within the source hierarchy, you need an IF to prevent the destination from being a source.
Before proceeding you should stop and think about what happens if the same file name appears in multiple source folders. You can only have one version in your destination folder. Can you guarantee no duplicate names exist? If not, which file should be kept? How can you structure the command to keep the file you want? This complication is probably why no command was ever written to simply flatten a hierarchy.
Here is your ROBOCOPY command integrated with the FOR /R solution.
#echo off
set source="R:\Contracts"
set destination="R:\Contracts\Sites"
::Not sure if this is needed
::It guarantees you have a canonical path (standard form)
for %%F in (%destination%) do set destination="%%~fF"
for /r %source% %%F in (.) do if "%%~fF" neq %destination% ROBOCOPY "%%F" %destination% *.srt *.pdf *.mp4 *.jpg /COPYALL /R:0
Similar to the previous Powershell option, I did the following to flatten a multi-subdirectory music folder:
#Get all files and not the directories
$files = Get-ChildItem -Path R:\Contracts -Recurse | Where {$_.PSIsContainer -eq $false}
#Copy items from sources to new destination
foreach ($file in $files){
Copy-Item -Path $file.FullName -Destination R:\Contracts\Sites\$($file.Name)
}
The Get-ChildItem with the -Recurse switch will get a listing of all sub-folders and files. The Where function is stripping out any directories by checking the boolean PSIsContainer property. Without stripping the directories the sub-folder structure would be created without files in them. This listing is stored in the $files variable.
The foreach function runs through the list of files in the $files variable and stores one item at a time in the $file variable. The Copy-Item function then uses the full path from $file.FullName and then copies the file to the destination with the same name from $file.Name.
I recently had to tackle this problem, and many files that I wanted to move to from the hierarchy to a single folder had the same name as each other, and I wanted to still flatten the hierarchy without them to being over-written.
What I did was write a script that moves the file, but renames it with the old hierarchy path in the name
for example:
source files:
C:\files\somefiles\file.txt
C:\files\otherfiles\file.txt
destination is C:\newdir\
files are created as
C:\newdir\somefiles-file.txt
C:\newdir\otherfiles-file.txt
here is the code, batch file 1 goes thru the files, batch file 2 renames and moves them (could also copy instead, if you want to preserve the source:
#echo off
for /r %%f in (*.*pr) do #renameandmovefilespart2.bat "%%f" "%%~ff" "%%~xf"
renameandmovefilespart2.bat
#echo off
Setlocal EnableDelayedExpansion
rem set the whole file path
set origWhole=%1
set origPathOnly=%2
set extension=%3
rem here you can set where the directory to hold the flattened hierarchy is
set destDir=c:\destinationDir\
rem set the directory to do a string replace
rem make this the starting directory, that you dont want in the newly renamed files
set startingDir=C:\starting\directory\
set nothing=
set slash=\
rem here you can set what the character to represent the directory indicator \ in the new files
set reaplcementDirectoryCharacter=--
set quote="
rem cut out the starting part of the directory
call set newname=%%origWhole:!startingDir!=!nothing!%%
rem replace slashes with new character
call set newname=%%newname:!slash!=!reaplcementDirectoryCharacter!%%
rem remove quotes
call set newname=%%newname:!quote!=!nothing!%%
rem #echo shortened: %newname%
rem #echo source path: %origPathOnly% newPath: %startingDir%
rem #echo extension: %extension%
rem rename the files
ren %origWhole% %newname%
rem prepare to move the file, clean up the source path
call set origPathOnly=%%origPathOnly:!quote!=!nothing!%%
move "%origPathOnly%%newname%" "%destDir%"
There's an old PCMag utility called Sweep.exe that can operate the same command in the current and subdirectory. I wouldn't put the destination as a subdirectory of the source directory. Put the destination elsewhere.
http://www.rarewares.org/files/case/Sweep.zip
cd c:\contracts
sweep copy *.* c:\sites
This will copy everything from c:\contracts and underneath to c:\sites
I use a similar command to flatten the hierarchy of a directory.
Take care with duplicates and how you want to handle them. Do you want to overwrite or handle a different way.
For those familiar with R copying files to a single folder could be easily scripted as follow. It is more efficient than ROBOCOPY for large sets and directory structures.
## R script - Flatten files in folder structure
# declare your paths
sourcepath<-C:\\Myfolder\\PicturesInStructure"
destpath<-"C:\\Myfolder\\PicturesTogether\\"
# read source filenames with path to vector variable
fileslist<-list.files(sourcepath,
pattern="*.jpg", # in this example copies JPG pictures
full.names=TRUE, # retrieves full path
recursive=TRUE, # runs through all subdirs
include.dirs=FALSE) # skips dir names (no to be copied)
# here you will get a head of your list
head(fileslist)
# ordinary loop by source filenames
for (i in 1:length(fileslist)) {
# Number of Slashes required to extract filename from the source path
NoS<-lengths(regmatches(fileslist[i], gregexpr("/", fileslist[i])))
# for lengthy processes it is good to know where you are with this
cat(i,fileslist[i]," \r")
# copy one file to a destination folder (full path composed with paste0())
file.copy(fileslist[i],paste0(destpath,unlist(strsplit(fileslist[i],"/"))[NoS+1]))
}