Using a batch file, how do I delete large, old files? - batch-file

I have temp files which are taking up a lot of disk space which I want to tidy on a scheduled basis using a batch file.
The file names I want to deal with always start with "harp_" but I want to keep the most recent 2 files.
For example the folder contains files such as:
harp_0tnqy2o078824m1ax 25/10/2016
harp_0e3qmw11gz6z9j10s 24/10/2016
harp_0tnqy2o078824m1ax 23/10/2016
harp_11ik03u00g4k2y19y 22/10/2016
Test 1 25/10/2016
Test 2 10/10/2016
I want the folder to just now contain:
harp_0tnqy2o078824m1ax 25/10/2016
harp_0e3qmw11gz6z9j10s 24/10/2016
Test 1 25/10/2016
Test 2 10/10/2016
Is anyone able to help me script the batch file for this?

You can use the FOR /F command to parse the output of the DIR command. The key is using the SKIP option so that it keeps the two newest files.
FOR /F "skip=2 delims=" %%G IN ('DIR /A-D /B /O-D harp_*') DO del "%%~G"

I'm quite unshure if batch ot bash is required. In case of batch my answer is like Squashman's adding an aspect of swecurity, files to be deleted are added to a tmp-file which might be revised edited before execution.
#Echo off&Setlocal
Set Basefldr=C:\where\ever
PushD "%Basefldr%" ||(Echo Couldn't cd to %Basefldr% &Pause&Exit /B 1)
Set DelList="%tmp%\DelList.cmd"
Type NUL>%DelList%
For /f "skip=2 delims=" %%A in ('Dir /B/A-D/O-D "harp_*"'
) Do >>%DelList% Echo:Del %%~fA
:: Review the file DelList.cmd before executing it
Notepad.exe %DelList%
:: or
:: more %DelList%
popd

Related

How to delete all hardlinks of multiple files on windows 10?

I create a lot of hardlinks every week. When time comes to clean them, I find myself using the "DeleteAllHardlinks.bat" for ln (https://schinagl.priv.at/nt/ln/ln.html) but I have to drag and drop everyfile one after the other.
I would love to find a way to just select 100 files and drop them on the .bat, wait a while and find all those files and hardlinks deleted for good. Is there anyway to change the .bat file to allow this? (or maybe any other different method to acomplish the same?)
#echo off
REM
REM Check for commandline args
REM
if "[%~1]" == "[]" goto error
set LN=ln.exe
REM
REM List hardlink sibblings and delete all siblings
REM
for /f "delims=" %%a in ('#%LN% --list "%~1"') do (
del /f "%%a"
)
goto ausmausraus
:error
echo DeleteAllHardlinks: Argument is missing. Usage DeleteAllHardlinks ^<filename^>
echo e.g. DeleteAllHardlinks c:\data\myfile.txt
:ausmausraus
echo on
Thanks in advance!
Big thanks to Mofi!
The batch file could be very easily modified to support not just first argument, but all file name argument strings passed to the batch file by using one more for loop and %* as explained by call /?, i.e. use as replacement for the existing for loop:
for %%I in (%*) do for /F "delims=" %%J in ('ln.exe --list "%%~I" 2^>nul') do del /F "%%~J"
But the application starting the batch file has to pass each file name enclosed in double quotes to work properly.
Just using the for as offered in the comment solved the issue perfectly.

Archiving every four files in a folder to a zip-file with a Windows batch file

I have a folder with Esri Shapes. Every Shape consists of 4 seperate files (.dbf, .prj, .shp, .shx). I want every shape archived in a seperate .zip file. Also, I want this .zip-file to have the same name as the shape it contains.
For example if I have the following files:
Test1.dbf
Test1.prj
Test1.shp
Test1.shx
Test2.dbf
Test2.prj
Test2.shp
Test2.shx
Then I want these files archived as below:
Test1.zip:
Test1.dbf
Test1.prj
Test1.shp
Test1.shx
Test2.zip:
Test2.dbf
Test2.prj
Test2.shp
Test2.shx
So I Reckoned this could be done with a batch-file and a FOR-loop. However, I don't know much about the code language needed to write a batch-file. I found some code elsewhere on Stackoverflow, but it returns only the .shp-files in the resulting .zip-files.
For example I get:
Test1.zip:
Test1.shp
Test2.zip:
Test2.shp
This code is:
#ECHO ON
SET SourceDir=sourcefolder
SET DestDir=destinationfolder
CD /D "C:\Program Files\7-Zip"
FOR /F "TOKENS=*" %%F IN ('DIR /B /A-D "%SourceDir%"') DO (
7z.exe a "%DestDir%\%%~NF.zip" "%SourceDir%\%%~NXF"
)
EXIT
Can someone tell me how to adjust this so to get all 4 components per shape in a single .zip-file?
As commented by Stephan and aschipfl, the code should look like this:
#ECHO ON
SET SourceDir=SourceFolder
SET DestDir=DestinationFolder
CD /D "C:\Program Files\7-Zip"
FOR /F "TOKENS=*" %%F IN ('dir /B /A:-D "%SourceDir%\*.prj"') DO (
7z.exe a "%DestDir%\%%~NF.zip" "%SourceDir%\%%~NF.*"
)
EXIT
The difference is found in the dir-command within the FOR-loop.

Rename Multiple Files in a folder using batch script

I have a folder called TEST. Inside there are 30 files.
Example:
DIM1_UPI_20170102.TXT
DIM2_UPI_20170908.TXT
DIM3_UPI_20180101.TXT
...
I have to rename them by removing the date tag
Exapmple:
DIM1_UPI.TXT
DIM2_UPI.TXT
DIM3_UPI.TXT
Can you please help me writing this in batch file?
Assuming your files are all starting with DIM
#echo off
setlocal enabledelayedexpansion
for /f %%i in ('dir "*.TXT" /b /a-d') do (
set "var=%%~ni"
echo ren !var!%%~xi !var:~0,-9!%%~xi
)
Once you can confirm that it does what you want, and ONLY then, remove the echofrom the last line to actually rename the files.
Important Note. If you have files with similar names, but different date entries, this will not work as you think. as Example:
DIM2_UPI_20170910.TXT
DIM2_UPI_20170908.TXT
The names are the same, but dates differ, making each filename Unique. If you rename them, there can be only 1 DIM2_UPI.TXT So as long as you understand this, you will be fine.
Edit: based on Amazon drive question. Note you need to change the directory portion to how you access amazon drive.
#echo off
setlocal enabledelayedexpansion
for /f %%i in ('dir "DIM*" /b /a-d') do (
set "var=%%~ni"
echo ren !var!%%~xi !var:~0,-16!%%~xi
)

How to insert a text in front of the filenames using a batch script

#echo off
for %%a in (*.xhtml) do (
ren "%%~fa" "epub_%%~nxa"
)
I am using the code for insert a text ("epub_") to all the file names.
The file name is
00_Cover_Page.xhtml
01_Halftitle.xhtml
02_Title.xhtml
03_Copyright.xhtml
04_Dedication.xhtml
05_Preface.xhtml
06_Contents.xhtml
It's renaming good except "00_Cover_Page.xhtml"
epub_epub_00_Cover_Page.xhtml ("epub_" Inserted twice in the filename only)
epub_01_Halftitle.xhtml
epub_02_Title.xhtml
epub_03_Copyright.xhtml
epub_04_Dedication.xhtml
epub_05_Preface.xhtml
epub_06_Contents.xhtml
How could it be happened?
As pointed out in MC ND's comment, an explanation of the behavior is available at https://stackoverflow.com/a/19705611/1012053. The FOR loop buffers only a portion of the directory, and when it goes back to disk to read additional file entries, it can pick up already renamed files.
jeb's answer on that same question explains how to avoid the problem by using a FOR /F loop processing a DIR /B command - the output of the DIR /B command is captured in its entirety before iterations begin.
#echo off
for /f "eol=: delims=" %%F in ('dir /b /a-d *.xhtml') do ren "%%F" "epub_%%~nxa"
An alternative is to use my JREN.BAT regular expression renaming utility. JREN.BAT is pure script (hybrid JScript/batch) that runs natively on any Windows machine from XP onward.
jren "^" "epub_" /fm *.xhtml
Use CALL JREN if you put the command within a batch script.
Somehow the FOR loop picks up the already renamed files. You can avoid this in (at least) 2 ways:
Filter on the orignal filenames if possible:
for %A in (0*.xhtml) do #ren "%~nxA" "epub_%~nxA"
Create a filename list beforehand and use it in the loop:
set tmpfile=files%RANDOM%.tmp
dir /b *.xhtml > %tmpfile%
for /f %A in (%tmpfile%) do #ren "%~nxA" "epub_%~nxA"
del %tmpfile%
set tmpfile=

Windows batch file: get last folder name from path

I'm trying to rename .jpg files which is in one of many subdirectories of e:\study\pubpmc\test\extracted.
I want to rename files to LastFolderName_ImageName.jpg.
(For example if Figure1.jpg is in e:\study\pubpmc\test\extracted\folder1
I want it to be renamed like this: folder1_Figure1.jpg)
So I need to take out the last folder name from the file's path.
Since it's my first time with batch scripting, I'm having a hard time.
I googled and made code similar to it
but it doesn't seem to work out.
Can you help me with it and tell me where I've done wrong?
Thank you! :)
#echo off
cd /D "e:\study\pubpmc\test\extracted"
for /r %%f in (*.jpg) do (
set mydir=%%~dpf
set mydir=%mydir:\=;%
for /f "tokens=* delims=;" %%i in (%mydir%) do call :LAST_FOLDER %%i
goto :EOF
:LAST_FOLDER
if "%1"=="" (
#echo %LAST%
goto :EOF
)
set LAST=%1
SHIFT
goto :LAST_FOLDER
)
JosefZ explains the obvious problems with your code, but he failed to point out a subtle problem, though his code fixed it:
FOR /R (as well as the simple FOR) begin iterating immediately, before it has finished scanning the disk drive. It is possible for the loop to reiterate the already named file! This would cause it to be renamed twice, giving the wrong result. The solution is to use FOR /F with command 'DIR /B', because FOR /F always processes the command to completion before iterating.
JosefZ also provides code that works for most situations. But there is a much simpler solution that works always:
#echo off
for /f "delims=" %%A in (
'dir /b /s /a-d "e:\study\pubpmc\test\extracted\*.jpg"'
) do for %%B in ("%%A\..") do ren "%%A" "%%~nxB_%%~nxA"
The "%%A\.." treats the file name as a folder and walks up to the parent folder. So %%~nxB gives the name of the parent folder.
The command could be run as a long one liner, directly from the command line (no batch):
for /f "delims=" %A in ('dir /b /s /a-d "e:\study\pubpmc\test\extracted\*.jpg"') do #for %B in ("%A\..") do #ren "%A" "%~nxB_%~nxA"
Avoid using :label and :: label-like comment inside (command block in parentheses). Using any of them within parentheses - including FOR and IF commands - will break their context.
Using variables inside (command block in parentheses). Read EnableDelayedExpansion: Delayed Expansion will cause variables to be expanded at execution time rather than at parse time [and CLI parses all the (command block in parentheses) at once]
Next script should work for you. Note rename statement is merely echoed for debugging purposes.
#ECHO OFF >NUL
SETLOCAL enableextensions disabledelayedexpansion
set "fromFolder=e:\study\pubpmc\test\extracted"
rem my debug setting set "fromFolder=D:\path"
for /F "tokens=*" %%f in ('dir /B /S /A:D "%fromFolder%\*.*"') do (
set "mydir=%%~ff"
set "last=%%~nxf"
call :renameJPG
)
#ENDLOCAL
goto :eof
:renameJPG
rem echo "%mydir%" "%last%"
for /f "tokens=*" %%i in ('dir /B /A:-D "%mydir%\*.jpg" 2^>nul') do (
echo ren "%mydir%\%%~nxi" "%last%_%%~nxi"
)
goto :eof
Resources:
SETLOCAL, disableDelayedExpansion, ENDLOCAL etc.
An A-Z Index of the Windows CMD command line
Windows CMD Shell Command Line Syntax
I already wrote a function for that. You give it any path and it returns you only it's filename or pathname. Works for any path: Url, Windows path, Linux path, etc...
Copy this function at the end of your batch script: (Instructions below)
rem ===========================================================================
:Name_From_Path
SetLocal
set _TMP_FOLDERNAME=%1
for %%g in ("%_TMP_FOLDERNAME%") do set _TMP_FOLDERNAME=%%~nxg
EndLocal & set _Name_From_Path=%_TMP_FOLDERNAME%
goto :EOF
rem ===========================================================================
Usage:
CALL :Name_Of_Path e:\study\pubpmc\test\extracted\folder1
ECHO %_Name_From_Path%
Result: folder1
If your program or com file traverses these folders when renaming, then it should be able to get the present working directory ( path ), pwd. You may be able to chop everything but the LAST_FOLDER out of this by also creating a PREVIOUS_FOLDER and doing a string replacement.
Or you may be able to break the folder names at the '\' token from the pwd into an array and use a -1 array reference to get the last folder name.
In any circumstance you'll want to check for a present working directory command.
If your creating a large text list of all these and issuing a single call to the batch file.
Then you may be better off with something like:
(Symmantic code warning )
(copy) /folderbase/some_folder/oneormore1/image_from_oneormore1.jpg (to) /folderbase/some_folder/oneormore1/oneormore1_image_from_oneormore1.jpg
Instead of copy, window uses rename, linux uses mv.
The latter example would require simply creating a duplicate list and replacing the \ with a _ while parsing through the tokens.
The code you've given is difficult to make sense of, so its hard to discern if you can simple concatenate the current folder and image name (stringify) and then write or rename them where they are.

Resources