Deleting file with space in the name in a loop - batch-file

I'm trying to delete every file bigger than a certain size in a directory but i'm not able to delete file with space in the name. The below script is what I have written to achieve the same.
#echo off
setlocal enabledelayedexpansion
set "MaxSize=3"
for /r %%I in (*) do (
echo %%I %%~zI Bytes
set /a kb=%%~zI/1024 + 1
echo !kb!Ko
if !kb! GTR %MaxSize% (
echo TIME : [%date%, %time%] ^| The size of the file %%I is !kb! Ko
the file is to big so the file was deleted >> Log_Remove.log
del /F %%I
echo file too big the file was deleted
) else (
echo file size is okay
)
)
Any idea about how i can delete the file with a space in the name ?

I've posted this as an addition to my comment, to show you an easier way of structuring your script.
#Echo off
Set "MaxKB=3"
Set /A MaxB=MaxKB*1024
For /R %%I In (*)Do If %%~zI Gtr %MaxB% (
Echo [%DATE%, %TIME%]: %%I was too large and therefore deleted>>"Log_Remove.log"
Del /A /F "%%I"
Echo file %%I was larger than %MaxKB% KB
)Else Echo file %%I was within %MaxKB% KB

Related

batch file, string manuplutation with dir command

Trying to get this to work.
Getting this line from dir: 3 File(s) 7,332,731,128 bytes and trying to just get the number of files to use for addition.
#Echo ON
dir %1 /a:h | find "File(s)" > hidden.txt
dir %1 | find "File(s)" > reg.txt
set /p hidden=<hidden.txt
echo %hidden%
IF /I "%hidden%"=="File Not Found" (
Set hidden = 0
) Else (
Set hidden=%hidden~-29%)
echo %hidden%
Set /p reg=<reg.txt
IF /I "%hidden%"=="File Not Found" (
set reg = 0
) ELSE (
Set reg=%reg~-29%)
set /a total = %reg% + %hidden%
Echo The total number of files in the %1 directory is: %total%. This includes hidden files.
Echo.
Echo The total number of non-hidden files in the %1 directory is: %reg%.
Echo.
Echo The total number of hidden files in the %1 directory is: %hidden%
you don't need temp files which only will slow down your script:
if you want to count the hidden files try this
#echo off
set counter=0
for /f %%# in ('dir /a:h-d "%~1"') do (
set /a counter=counter+1
)
echo hidden files=%counter%
to count all files
#echo off
set counter=0
for /f %%# in ('dir /a:-d "%~1"') do (
set /a counter=counter+1
)
echo all files=%counter%
This is just another For loop option:
#For /F %%A In ('Dir/AH-D-L "%~1" 2^>Nul') Do #If Not "%%A"=="0" Set "fileCount=%%A"
#Echo %fileCount%
#Pause
Remove -L, if you wish not to exclude junction points from your file count.
I've got the same result with just two FOR loops. Using sentences between single quotes inside the parentheses we can execute commands and store results.
I've left the same Result Text just to let you compare and see if this is what you're looking for:
CODE:
#echo off
setlocal
for /f %%A in ('dir "%~1" /a-h-d /b ^| find /V /C ""') do set "visCount=%%A"
for /f %%A in ('dir "%~1" /ah-d /b ^| find /V /C ""') do set "hidCount=%%A"
set /a totalCount = visCount + hidCount
echo.
echo The total number of files in the %1 directory is: %totalCount%. This includes hidden files.
echo.
echo The total number of non-hidden files in the %1 directory is: %visCount%.
echo.
echo The total number of hidden files in the %1 directory is: %hidCount%
With /B parameter of DIR command I only get one line per file and no more text, and with /A I can select Hidden or not files and no directories.
Then SET /A command let us use arithmetics operations.

Windows Batch FOR Loop improvement

I have a batch to check the duplicate line in TXT file (over one million line) with 13MB, that will be running over 2hr...how can I speed up that? Thank you!!
TXT file
11
22
33
44
.
.
.
44 (over one million line)
Existing Batch
setlocal
set var1=*
sort original.txt>sort.txt
for /f %%a in ('type sort.txt') do (call :run %%a)
goto :end
:run
if %1==%var1% echo %1>>duplicate.txt
set var1=%1
goto :eof
:end
This should be the fastest method using a Batch file:
#echo off
setlocal EnableDelayedExpansion
set var1=*
sort original.txt>sort.txt
(for /f %%a in (sort.txt) do (
if "%%a" == "!var1!" (
echo %%a
) else (
set "var1=%%a"
)
)) >duplicate.txt
This method use findstr command as in aschipfl's answer, but in this case each line and its duplicates are removed from the file after being revised by findstr. This method could be faster if the number of duplicates in the file is high; otherwise it will be slower because the high volume data manipulated in each turn. Just a test may confirm this point...
#echo off
setlocal EnableDelayedExpansion
del duplicate.txt 2>NUL
copy /Y original.txt input.txt > NUL
:nextTurn
for %%a in (input.txt) do if %%~Za equ 0 goto end
< input.txt (
set /P "line="
findstr /X /C:"!line!"
find /V "!line!" > output.txt
) >> duplicate.txt
move /Y output.txt input.txt > NUL
goto nextTurn
:end
#echo off
setlocal enabledelayedexpansion
set var1=*
(
for /f %%a in ('sort q42574625.txt') do (
if "%%a"=="!var1!" echo %%a
set "var1=%%a"
)
)>"u:\q42574625_2.txt"
GOTO :EOF
This may be faster - I don't have your file to test against
I used a file named q42574625.txt containing some dummy data for my testing.
It's not clear whether you want only one instance of a duplicate line or not. Your code would produce 5 "duplicate" lines if there were 6 identical lines in the source file.
Here's a version which will report each duplicated line only once:
#echo off
setlocal enabledelayedexpansion
set var1=*
set var2=*
(
for /f %%a in ('sort q42574625.txt') do (
if "%%a"=="!var1!" IF "!var2!" neq "%%a" echo %%a&SET "var2=%%a"
set "var1=%%a"
)
)>"u:\q42574625.txt"
GOTO :EOF
Supposing you provide the text file as the first command line argument, you could try the following:
#echo off
for /F "usebackq delims=" %%L in ("%~1") do (
for /F "delims=" %%K in ('
findstr /X /C:"%%L" "%~1" ^| find /C /V ""
') do (
if %%K GTR 1 echo %%L
)
)
This returns all duplicate lines, but multiple times each, namely as often as each occurs in the file.

How to scan a folder and store all file names in a array variable and then loop through the array?

I am new to batch and I am trying to do the following:
reading or scanning a folder
hold all file names in folder in an array variable (need to hold file name with or without extension)
loop through that array and create a call to a specific file/bat based on the type of file using an IF or CASE statement condition. example: if the filename has the word person in it, call a specific file/bat.
This is what I have so far:
#echo off
setlocal EnableDelayedExpansion
rem Populate the array with existent files in folder
set i=0
for %%b in (*.*) do (
set /A i+=1
set list[!i!]=%%b
)
set Filesx=%i%
rem Display array elements
for /L %%i in (1,1,%Filesx%) do echo !list[%%i]!
... do (
echo !list[%%i]! | find /i "person" >nul && call specific.bat !list[%%i]!
)
echo !list[%%i]! | find /i "person": find the word
>nul: disregard the output (we don't need it, just the errorlevel)
&&: if previous command was successful (the word was found), then...
Do you really need that array? You can do it "on the fly":
for %%b in (*.*) do (
echo %%b | find /i "person" >nul && call specific.bat "%%b"
)
for filename only, use %%~nb, for full name (including path), use %%~fb (see for /? for more options)
This a quick modified version from : Open a file through cmd and display the selected in specific editor
It will scan on your desktop for any batch files which contains the word : person
#ECHO OFF
Title Scan a folder and store all files names in an array variables
:MenuLoop
Cls & Color 0A
SETLOCAL
SET "ROOT=%userprofile%\Desktop\"
SET "EXT=*.bat"
SET "Count=0"
Set "Word2Search=Person"
SETLOCAL enabledelayedexpansion
REM Iterates throw the files on this current folder.
REM And Populate the array with existent files in folder
FOR /f "delims=" %%f IN ('dir /b /s "%ROOT%\%EXT%"') DO (
find /I "%Word2Search%" "%%f" >nul 2>&1 && (
SET /a "Count+=1"
set "list[!Count!]=%%~nxf"
set "listpath[!Count!]=%%~dpFf"
) || (
Call :Scanning
)
)
echo wscript.echo Len("%ROOT%"^) + 20 >"%tmp%\length.vbs"
for /f %%a in ('Cscript /nologo "%tmp%\length.vbs"') do ( set "cols=%%a")
If %cols% LSS 50 set /a cols=%cols% + 15
set Files=%Count%
set /a lines=%Count% + 10
Mode con cols=%cols% lines=%lines%
ECHO *******************************************************
ECHO Folder : "%ROOT%"
ECHO *******************************************************
echo(
rem Display array elements
for /L %%i in (1,1,%Files%) do echo [%%i] : !list[%%i]!
SET /a "COUNT_TOT=%Count%"
ECHO.
ECHO Total of [%EXT%] files(s) : %Count% file(s)
echo(
echo Type the number of what file did you want to edit ?
set /p "Input="
set "sublimeEXE=%programfiles%\Sublime Text 3\sublime_text.exe"
For /L %%i in (1,1,%Count%) Do (
If "%INPUT%" EQU "%%i" (
Rem Testing if sublime_text.exe exist to open with it the text file
If Exist "%sublimeEXE%" (
Start "Sublime" "%sublimeEXE%" "!listpath[%%i]!"
Rem Otherwise we open the text file with defalut application like notepad
) else (
Start "" Notepad.exe "!listpath[%%i]!"
)
)
)
EndLocal
Goto:MenuLoop
:Scanning
mode con cols=75 lines=3
Cls & Color 0A
echo(
echo Scanning in progress ...
goto :eof

Windows Batch - Find all pdf's in sub directories, exclude specific foldernames

Context
I'm currently programming with batch files, to use a specific pdf tool only available for cmd.
Problem
I'm trying to run a for loop, which recursively cycles through a directory finding all *.pdf files. Excluding the pdf's inside folders named "Originals"
If the pdf file is in a parent folder named "Originals", then it must be skipped. Otherwise count the pdf file with the %counter% variable.
Example Directory Structure
C:\New folder\file (1).pdf
C:\New folder\file (2).pdf
C:\New folder\Sub_1\file (1).pdf
C:\New folder\Sub_1\file (2).pdf
C:\New folder\Sub_1\file (3).pdf
C:\New folder\Sub_2\file (4).pdf
C:\New folder\Sub_2\file (5).pdf
C:\New folder\Originals\file (1).pdf
C:\New folder\Originals\file (2).pdf
Example batch file - Find all pdf's (excluding Originals)
:: Example.bat
#echo off
set myDirectory=C:\New folder
:: Search through myDirectory to find all .pdf files (including subdirectories)
setlocal enableDelayedExpansion
for /R "%myDirectory%" %%G in (*.pdf) do (
set inputDirectory=%%~dpG
echo G = !%%G!
echo inputDirectory = !inputDirectory!
for /f "delims=\" %%F in ("!inputDirectory!") do (
set currentFolder=%%~nxF
echo currentFolder = !currentFolder!
)
if NOT "!currentFolder!"=="Originals" (
set /a count=count+1
)
)
echo There are %count% PDF's (excluding originals)
pause
Please run the example batch file to demonstrate what I have so far. Any help or solutions would be appreciated.
Cheers!
Solved
Here's what I came up with based on everyone's solutions!
#echo off
setlocal enabledelayedexpansion
set count=0
set myDirectory=C:\New folder
for /r "%myDirectory%" %%i in (*.pdf) do (
set inputDirectory=%%~dpi
set inputDirectoryNoSlash=!inputDirectory:~0,-1!
for %%j in (!inputDirectoryNoSlash!) do set sub=%%~nxj
if NOT !sub!==Originals (
set /a count=count+1
)
)
echo There are %count% PDF's (excluding originals)
pause
Thanks again guys!
Another similar method is:
#echo off
setlocal enabledelayedexpansion
set count=0
set dir=C:\TEST
echo %count%
for /r "%dir%" %%i in (*.pdf) do (
set dirx=%%~dpi
set con=!dirx:~0,-1!
for %%j in (!con!) do set sub=%%~nxj
if !sub!==Originals (
cls
) else (
set /a count=count+1
)
)
echo !count!
pause
*Change to appropriate pathname
%%~pG Expand %%G to a Path only including a trailing \ backslash. Undesired, clear it away as follows:
for /f "tokens=* delims=\" %%F in ("!inputDirectory:~0,-1!") do (
set currentFolder=%%~nxF
echo currentFolder = !currentFolder!
)
Try this:
#echo off
setlocal EnableDelayedExpansion
set myDirectory=C:\New folder
set count=0
for /F "delims=" %%a in ('dir /S "%myDirectory%\*.pdf" ^| findstr /V /L "\Originals\"') do (
echo File: %%a
set /A count+=1
)
echo There are %count% PDF's (excluding originals)
pause

Deleting last n lines from file using batch file

How to delete last n lines from file using batch script
I don't have any idea about batch files, I am writing batch file for the first time.
How should I write this batch file?
For Windows7
Try it for
<Project_Name>
<Noter>
<Common>
<File>D:\Project_Name\Util.jar</File>
<File>D:\Project_Name\Noter.bat</File>
<File>D:Project_Name\Noter.xml</File>
<File>D:Project_Name\Noter.jar</File>
</Common>
<Project_Name>
<File>D:\Util.bat</File>
<File>D:\Util.xml</File>
<File>D:\log.bat</File>
</Project_Name>
</Noter>
<CCNET>
This the complete script for remove last N line
count the total line
set Line = Line - N , remain just processing lines number
#echo OFF
setlocal EnableDelayedExpansion
set LINES=0
for /f "delims==" %%I in (infile.txt) do (
set /a LINES=LINES+1
)
echo Total Lines : %LINES%
echo.
:: n = 5 , last 5 line will ignore
set /a LINES=LINES-5
call:PrintFirstNLine > output.txt
goto EOF
:PrintFirstNLine
set cur=0
for /f "delims==" %%I in (infile.txt) do (
echo %%I
::echo !cur! : %%I
set /a cur=cur+1
if "!cur!"=="%LINES%" goto EOF
)
:EOF
exit /b
Here call:PrintFirstNLine > output.txt will give the output in an external file name as output.txt
Output for sample Input
<Project_Name>
<CBA_Notifier>
<Common>
<File>D:\CBA\CBA_Notifier\Project_Name\IPS-Util.jar</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.bat</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.xml</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.jar</File>
</Common>
<Project_Name>
<File>D:\CBA\CBA_Notifier\IPS-Util.bat</File>
remove last 5 line
Update
:PrintFirstNLine
set cur=0
for /F "tokens=1* delims=]" %%I in ('type "infile.txt" ^| find /V /N ""') do (
if "%%J"=="" (echo.) else (
echo.%%J
set /a cur=cur+1
)
if "!cur!"=="%LINES%" goto EOF
)
This script will takes 1 arguement, the file to be trunkated, creates a temporary file and then replaces the original file with the shorter one.
#echo off
setlocal enabledelayedexpansion
set count=
for /f %%x in ('type %1 ^| find /c /v ""') do set /a lines=%%x-5
copy /y nul %tmp%\tmp.zzz > nul
for /f "tokens=*" %%x in ('type %1 ^| find /v ""') do (
set /a count=count+1
if !count! leq %lines% echo %%x>>%tmp%\tmp.zzz
)
move /y %tmp%\tmp.zzz %1 > nul
If the original file is 5 or less lines, the main output routine will noT create a file. To combat this, I use the copy /y null to create a zero byte file.
If you would rather not have an empty file, just remove the copy /y nul line, and replace it with the following line:
if %lines% leq 0 del %1
You should use one method or the other, otherwise source files with 5 or less lines will remain untouched. (Neither replaced or deleted.)
to delete last lines from your file,
1 copy starting lines that are needed from file like from- e:\original.txt
2 paste them in new file like- e:\new\newfile1.txt
code is thanks to the person giving me this code:
remember all may be done if you have motive and even blood hb =6. but help of nature is required always as you are a part of it
#echo off & setLocal enableDELAYedeXpansion
set N=
for /f "tokens=* delims= " %%a in (e:\4.txt) do (
set /a N+=1
if !N! gtr 264 goto :did
e:\new4.txt echo.%%a
)
:did
if you have 800 files then use excel to make code for 800 and then copy it to notepad and using Ctrl+h replace space with no space. then rename file as haha.bat . run in folder with files numbered 1.txt 2.txt 3.txt etc. any enquirers welcome Erkamaldev#gmail.com " Long Live Bharata"
A slow method with less coding:
set input=file.txt
set remove=7
for /f "delims=" %i in ('find /c /v "" ^< "%cd%\%input%"') do set lines=%i
set /a lines-=remove
for /l %i in (1,1,!lines!) do findstr /n . log.txt | findstr /b %i:
May be redirected to a file.
Each line is prefixed with the line number; may be removed with extra coding.
A faster version with /g flag in my answer at:
How to split large text file in windows?
Tested in Win 10 CMD, on 577KB file, 7669 lines.

Resources