Discussion:
Unsuccessful batch...
(too old to reply)
Laurent Jumet
2012-09-25 08:16:53 UTC
Permalink
Hello !

I'm unsuccessfully trying to make a batch that searchs a directory looking for file with different name but same size, and delete one of them.
This batch almost works, but it doesn't detect the secund file with the same size.


=== Begin DUPEVID.BTM ===
setlocal
if not ISDIR H:\prov GOTO FAIL1
pushd H:\prov

DIR /B /Os *.flv | for %loop in (@con) gosub dupe_strip
DIR /B /Os *.mp4 | for %loop in (@con) gosub dupe_strip
DIR /B /Os *.wmv | for %loop in (@con) gosub dupe_strip
DIR /B /Os *.avi | for %loop in (@con) gosub dupe_strip

ENDLOCAL
QUIT

:dupe_strip
set first=%@findfirst[%loop]
set second=%@findnext[]
if "%second" == "" return

IFF %@filesize[%first] EQ %@filesize[%second] THEN
SET delete=(%second)
ELSE
RETURN
ENDIFF

:: the next routine will delete the duplicate file.

del %delete
RETURN

:FAIL1
PAUSE Le dossier n'existe pas...
POPD
endlocal
QUIT
=== End DUPEVID.BTM ===
--
Laurent Jumet - Point de Chat, Liège, BELGIUM
KeyID: 0xCFAF704C
[Restore address to laurent.jumet for e-mail reply.]
E. S. Fabian
2012-09-25 10:01:41 UTC
Permalink
Dear Laurent Jumet:

From the text of your message and from the code I assume you want to keep
only a single file of a specific size AND extension. What you do not specify
is the command processor version you want to use. Let me suggest the
following comments, regardless of the command processor:

1/ The reason your program deletes only one file of matching size is that
@findnext[] is not repeated after a match to find the next match. But what
is strange is that there is no wildcard in the parameter to @findfirst[], so
@findnext should never find a second match.

2/ Since you do not include @findclose[], you may run out of memory when
there are too many files.

3/ Since the size of each file is stored in the same block on disk as its
name, you can get much better performance from using DIR to obtain both name
and size. If using TCC, or a version of 4NT which supports the PDIR command,
you could retrieve just size and name to a temporary file.

4/ Your original program does not work for files whose name must be quoted
(embedded space or other special characters). I did not try to improve on
that issue.

An alternate program is below. UNTESTED!!! To the best of my knowledge it
ought to work in 4DOS as well as 4NT and TCC.

@echo off

:: report absent work directory and quit
iff not ISDIR H:\prov then
PAUSE Le dossier n'existe pas...
QUIT
endiff

:: make directories and variables etc. local
setlocal

:: create a file for temporary data
set x=%@unique[%temp]

:: ensure the temporary data file is erased on abnormal exit
on error goto CLEANUP
on break goto CLEANUP

:: go to work directory (ENDLOCAL restores original directory)
cdd H:\prov

:: repeat work for all file name extensions of interest
do ext in /l flv mp4 wmv avi

:: save date, time, size and name of each file of specific extension
:: ordered by filesize in temporary file
dir /os *.ext >! %x

:: initialize auxiliary variable
set oldsize=-1

:: cycle through all lines of temporary file
do new in @%x

:: size is word 2 in DIR output record
set newsize=%@word[2,%new]

:: check if current record is for a file of same size as a previous one
iff %newsize EQ %oldsize then

:: same size, new file deleted
del %@word[-0,%new]
else
:: different size, reference size updated
set oldsize=%newsize
endiff
enddo
enddo

:CLEANUP
:: delete temporary file
del %x
--
HTH, Steve

:: implied ENDLOCAL - restores original directory

PS:
Laurent Jumet
2012-09-25 10:08:41 UTC
Permalink
Hello E. !
Post by E. S. Fabian
From the text of your message and from the code I assume you want to keep
only a single file of a specific size AND extension. What you do not specify
is the command processor version you want to use. Let me suggest the
I'm working on
TCC 11,00,52 Windows XP [Version 5,1,2600]
Post by E. S. Fabian
1/ The reason your program deletes only one file of matching size is that
@findnext[] is not repeated after a match to find the next match. But what
@findnext should never find a second match.
This batch works perfectly:
(And the second one below doesn't seem to work, despite the syntax sounds quite the same.)

=== Begin DUPEDIFF.BTM ===
setlocal
unset *
pushd d:\files
text | for %loop in (@con) gosub dupe_strip
allirhov.*
cdirhov.*
milkhd.*
fm170pnt.*
fm180pnt.*
fm320pnt.*
fmekofer.*
fmekofls.*
fmekomsg.*
fmlist.*
fmpoint.*
hobnode.*
hobpoint.*
mednodes.*
nodediff.*
nodewal.*
os2list.*
outline.*
present.ex?
pvtlist.*
r29point.*
293pnt.*
walpoint.*
siliprx.*
endtext
popd
endlocal
quit

:dupe_strip
set first=%@findfirst[%loop]
set second=%@findnext[]

:: no need to check the 'first' variable

if "%second"=="" return

:: the next routine will delete the older file. If the first file is as
:: old as the second file, the first file will be deleted.

set delete=%first
if %@fileage[%first] gt %@fileage[%second] set delete=%second
del %delete
return
=== End DUPEDIFF.BTM ===


=== Begin DUPEVID.BTM ===
setlocal
if not ISDIR H:\prov GOTO FAIL1
pushd H:\prov
:: text | for %loop in (@con) gosub dupe_strip
:: *.flv
:: *.mp4
:: *.wmv
:: *.avi
:: endtext
ECHO ON

DIR /B /Os *.flv | for %loop in (@con) gosub dupe_strip
DIR /B /Os *.mp4 | for %loop in (@con) gosub dupe_strip
DIR /B /Os *.wmv | for %loop in (@con) gosub dupe_strip
DIR /B /Os *.avi | for %loop in (@con) gosub dupe_strip

QUIT

:dupe_strip
set first=%@findfirst[%loop]
set second=%@findnext[]
if "%second" == "" return

IFF %@filesize[%first] EQ %@filesize[%second] THEN
SET delete=(%second)
ELSE
RETURN
ENDIFF

:: the next routine will delete the duplicate file.

del %delete
RETURN

:FAIL1
PAUSE Le dossier n'existe pas...
POPD
endlocal
QUIT
=== End DUPEVID.BTM ===
--
Laurent Jumet - Point de Chat, Liège, BELGIUM
KeyID: 0xCFAF704C
[Restore address to laurent.jumet for e-mail reply.]
E. S. Fabian
2012-09-25 17:14:59 UTC
Permalink
Dear Laurent Jumet:

I tried dupediff.btm with both TCC 11.00.52 and 14.02.38 (latest), on WinXP
home SP3 platform. It failed in the "piped to" process, i.e., on the right
side of

TEXT | for %loop in (@con) gosub dupe_strip

Removing the line "unset *" solved this problem. Apparently my environment
requires PATH and probably other variables.

Instead of deleting files, I put in commands into the subroutine to just
display the values of LOOP, FIRST, and SECOND. I added to the list *.BTM,
and executed it in a directory containing 5 matching files. Below are the
first 3 lines of the display:

loop= *.btm first=DUPED.BTM second=DUPEDIFF.BTM
loop= allirhov.* first=** not defined ** second=** not defined **
loop= cdirhov.* first=** not defined ** second=** not defined **

Notice that the wildcards are not expanded by the FOR, they are considered
lines of text to be used literally (see the "Retrieving Text from Files"
paragraph in help topic FOR), and were passed to @findfirst/@findnext (BTW,
I added a statement "set dummy=%@fileclose[]" to the subroutine). As a
consequence, only 2 of the 5 files matching *.BTM were ever seen by the
program... and only one as "first". I doubt that is your intention.

More later.
--
Steve
E. S. Fabian
2012-09-25 18:01:20 UTC
Permalink
Sorry, I wrote "@fileclose[]" when I meant "@findclose[]".
--
Steve
Laurent Jumet
2012-09-26 06:19:03 UTC
Permalink
Hello E. !
Post by E. S. Fabian
I tried dupediff.btm with both TCC 11.00.52 and 14.02.38 (latest), on WinXP
home SP3 platform. It failed in the "piped to" process, i.e., on the right
side of
Removing the line "unset *" solved this problem. Apparently my environment
requires PATH and probably other variables.
Instead of deleting files, I put in commands into the subroutine to just
display the values of LOOP, FIRST, and SECOND. I added to the list *.BTM,
and executed it in a directory containing 5 matching files. Below are the
loop= *.btm first=DUPED.BTM second=DUPEDIFF.BTM
loop= allirhov.* first=** not defined ** second=** not defined **
loop= cdirhov.* first=** not defined ** second=** not defined **
Notice that the wildcards are not expanded by the FOR, they are considered
lines of text to be used literally (see the "Retrieving Text from Files"
consequence, only 2 of the 5 files matching *.BTM were ever seen by the
program... and only one as "first". I doubt that is your intention.
On my system, all files piped with "DIR /B /Os" appear in the subroutine and in %first; but %second is always empty, even in the first match.
--
Laurent Jumet - Point de Chat, Liège, BELGIUM
KeyID: 0xCFAF704C
[Restore address to laurent.jumet for e-mail reply.]
Laurent Jumet
2012-09-26 08:23:36 UTC
Permalink
Hello E. !
Post by E. S. Fabian
I tried dupediff.btm with both TCC 11.00.52 and 14.02.38 (latest), on WinXP
home SP3 platform.
Notice that the wildcards are not expanded by the FOR, they are considered
lines of text to be used literally (see the "Retrieving Text from Files"
a consequence, only 2 of the 5 files matching *.BTM were ever seen by the
program... and only one as "first". I doubt that is your intention.
...yes, you are right. This batch works only for one dupe per extension, but not to explore a directory.
Need a little more work.

=== Begin DUPEVID.BTM ===
setlocal
if not ISDIR H:\prov GOTO FAIL1
pushd H:\prov
ECHO ON

text | for %loop in (@con) gosub dupe_strip
*.flv
*.mp4
*.wmv
*.avi
endtext

QUIT

:dupe_strip
set first=%@findfirst[%loop]
set second=%@findnext[]
ECHO %loop %first %second
if "%second" == "" (ECHO %@FINDCLOSE[] & return)

IFF %@filesize[%first] EQ %@filesize[%second] THEN
SET delete=(%second)
ELSE
RETURN
ENDIFF

:: the next routine will delete the duplicate file.

del %delete
ECHO %@FINDCLOSE[]
RETURN

:FAIL1
PAUSE Le dossier n'existe pas...
POPD
endlocal
QUIT
=== End DUPEVID.BTM ===
--
Laurent Jumet - Point de Chat, Liège, BELGIUM
KeyID: 0xCFAF704C
[Restore address to laurent.jumet for e-mail reply.]
Harald Peters
2014-04-22 21:30:21 UTC
Permalink
Op Tue, 25 Sep 2012 10:16:53 +0200 schreef Laurent Jumet
Post by Laurent Jumet
Hello !
I'm unsuccessfully trying to make a batch that searchs a directory
looking for file with different name but same size, and delete one of
them.
This batch almost works, but it doesn't detect the secund file with the same size.
=== Begin DUPEVID.BTM ===
setlocal
if not ISDIR H:\prov GOTO FAIL1
pushd H:\prov
ENDLOCAL
QUIT
:dupe_strip
if "%second" == "" return
SET delete=(%second) <= you
return anywaste - no action
< insert misplaced >
Post by Laurent Jumet
ELSE
RETURN
ENDIFF
:: the next routine will delete the duplicate file.
del %delete <=
misplaced out of IFF
RETURN
:FAIL1
PAUSE Le dossier n'existe pas...
POPD
endlocal
QUIT
=== End DUPEVID.BTM ===
--
Gemaakt met Opera's e-mailprogramma: http://www.opera.com/mail/
Loading...