List files at 2 directories and compare - windows

I search for duplicates in two folders. Therefor I use Windows "cmd". I want to list all files and folders which are located beneath 2 different folders. The list of files are written to two textfiles. Then I want to compare the results which are listed inside the two textfiles.
My goal is to get a list of duplicate files or folders by comparing the textfile-lists.
So far I have some commands which are helpful (but the job is not done perfectly):
forfiles /p F:\firstfolder-01 /S /M *.* /C "cmd /c echo #file #fsize #fdate #ftime" >> filelist-01.txt
forfiles /p F:\secondfolder-02 /S /M *.* /C "cmd /c echo #file #fsize #fdate #ftime" >> filelist-02.txt
fc filelist-01.txt filelist-02.txt > dublicate-results.txt

Use the findstr command to get the duplicate lines:
findstr /LIXG:"filelist-01.txt" "filelist-02.txt"
To write the output to another file, use output redirection (>):
findstr /LIXG:"filelist-01.txt" "filelist-02.txt" > "filelist-dups.txt"

Related

When I put a batch program in the task scheduler, it didn't finish the whole task, so why did this happen?

This problem is from the scheduler task, batch program, or the files in a folder that I want to delete it using the batch program?
and this is the batch program:
forfiles /p "D:\nameOfFolder" /s /m *.* /d -7 /c "cmd /c del #path"
Replace /M *.* by /M * to even include files without extension, because forfiles treats wildcards differently than most other commands. /M * may even be omitted since this is the default setting anyway.
Regard that forfiles iterates both files and directories, so you need to exclude the latter, because del may try to delete its contents then. Therefore, implement a condition based on the forfiles-specific variable #isdir.
forfiles /S /P "D:\nameOfFolder" /M * /D -7 /C "cmd /D /C if #isdir==FALSE del #path"
As a side note, never append a trailing backslash to a (quoted) path, because something like /P "D:\" would let the command fail since \" constitutes an escaped quotation mark for forfiles, ruining the command line. You may however specify /P "D:\.".
Are you sure you even have such files?
I tried the following (very similar) command:
forfiles /p "C:\Temp_Folder" /s /m . /d -7 /c "cmd /c echo #path"
ERROR: No files found with the specified search criteria.
One thing I noticed, is that the name of the directory should not end with a backslash:
forfiles /p "C:\Temp_Folder" is working fine.
forfiles /p "C:\Temp_Folder\" is not working.
. on its own is not a valid searchmask to supply to /m.
You ned to use *.* (all) *.ext (the supplied extension) *string*.* (files with names containing the string).
? is also supported as a searchmask to match any character. example: *.?a* would match any file with an extension type with a as the second character

Windows Batch:Count the number of files deleted using forfiles command

I have written a simple batch job for copying the files from one folder to another that are older than x-number of days using forfiles. But I need to count the number of files that have been copied. I tried various ways to do this but was unsuccessful. Could any body help me trough this?
#Echo off
Echo Starting the script for copying files to other folder.
set dt=%date:~10,4%-%date:~4,2%-%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%
set filesMovedCount=0
forfiles /p C:\symphonybackup\symphonybackup\Symphony\SymphonyArcheive /s /m *.* /d -30 /c "cmd /c echo #path >> C:\symphonybackup\symphonybackup\Symphony\%dt%.log & cmd /c copy #path C:\symphonybackup\symphonybackup\Symphony\SymphonyTemp"
Echo filesmovedcount:%filesMovedCount%
Echo finised copying the files
You could just pipe all of your copied file names to a file and then count the rows in the file. Here I added the additional stuff, you can just add the commands where the output gets piped to logfile where indicated. When done, it will echo the count and you delete the file.
#echo off
forfiles /p "rest of copy commands" >>logfile.txt
setlocal EnableDelayedExpansion
set "string=findstr /R /N "^^" logfile.txt | find /C ":""
for /f %%a in ('!string!') do set count=%%a
echo %count% files copied
del /Q logfile.txt
Mayby late answer to this, but when I try this:
set "string=findstr /R /N "^^" logfile.txt | find /C ":""
for /f %%a in ('!string!') do set count=%%a
I get one extra result since I get one empty row. So I did need have to add -1 to the result.
Atleast on my system...

FORFILES no longer recursive when used with FOR loop

I have this code below in a batch file (Windows). It returns a list of paths for each .jpg file in a directory. Then passes that list to the ImageMagick Convert function (not the Windows convert) to create a pdf.
echo moving CMD to drive location at %~dp1
CD /d %~dp1
echo getting the list of file names
FORFILES /p %~dp1 /s /m "*.jpg" /C "cmd /c echo #path" > files.txt
echo creating the pdf using ImageMagick
convert #files.txt test.pdf
This works fine for returning the jpg image data or another single file type. I need it to search for multiple image file types and I have seen this example solution where you can put the FORFILES into a FOR loop.
for %%G in ( .jpg , .tif ) do FORFILES /p %~dp1 /s /m "*.jpg" /C "cmd /c echo #path" > files.txt
But if I do that the program is no longer recursive. The /s in forfiles no longer works.
I have tried FOR /R but it doesn't handle folder names with spaces which I need to be able to do.
Any thoughts on how to keep this recursive and not have issues with folder names with spaces?
#Lưu Vĩnh Phúc
thank you for responding. I tried what you said but For /F was throwing an error where it thought .jpg was a file and it couldnt find it.
You did force me to try new things and in doing so I think it was just my syntax that was the issue. I changed the code to this:
FOR %%G in (.jpg, .tif) do FORFILES /p %~dp1 /s /m *%%G /C "cmd /c echo #path" >> files.txt
Where I removed the /r or /f and added the variable from the for loop to the forfiles loop.
This keeps its recursive nature and returns only the file types listed in the for loop.

Windows batch script for searching files based on file name,checks if the files are older than N days, if true, it deletes those files

I am a newbie to windows batch scripting. I have researched through the web and the site and tried out the solutions but none seem to give me the desired results.
This is what I want to achieve:
Search for files in a folder using a specific filename
show found files
Check the found files if they are older than 1 day
If true,delete those files
Else return message(Found files not older than 1 day)
From my research I was able to write a batch code that searches for file using a string, but unable to do step 2,3,4 and 5.
Kindly assist.
Here is my batch code:
#echo off & setlocal
set "MySearchString=Scheduled_error"
for /r %%a in (*) do for /f "delims=" %%i in ('echo("%%~na" ^| findstr /i "%MySearchString%"') do echo del "%%~fa"
Seems like a perfect task for FORFILES!
forfiles /p c:\SomePath\ /s /m *.* /c "cmd /c echo #path" will show you all files older than one day. You can modify the filter replacing *.* with the file name you are looking for.
To delete these files simply replace echo #path with del /y #path and add the /d -1 parameter:
forfiles /p c:\SomePath /s /m *.* /d -1 /c "cmd /c del /y #path"
The age of the files to delete is specified with the /d -1 switch where -1 means 1 day and older.

forfiles in certain subfolder in multiple folders

Is there away to only display files in a folder called "Export", when such a subfolder is in multiple locations?
This will display all .xlsx files below where I'm running the batch file from, however I don't want to display all, I only want to display things in a folder called "Export":
forfiles -p "%~dp0\" -s -m *.xlsx -d -365 -c "cmd /c ECHO #relpath"
I have attempted things like:
forfiles -p "%~dp0\*\Export" -s -m *.xlsx -d -365 -c "cmd /c ECHO #relpath"
However it doesn't recognise syntax like this. Says invalid argument/option, but they are valid until I add *\ to the path.
This is an example of the structure I'm working with and what I what results to display:
%~dp0\1\Exports\Excel\ - (Do display .xlsx files)
%~dp0\1\Do Not Delete\Excel\ - (Don't display .xlsx files)
%~dp0\2\Exports\Excel\ - (Do display .xlsx files)
%~dp0\2\Do Not Delete\Excel\ - (Don't display .xlsx files)
The number folders would be a variable somehow, which is why the *\ is in my attempt.
I will then edit this to delete the files when I know it's picking up the right ones.
You could use two nested forfiles loops:
forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C echo 00x7840path0x22"
This command line walks through the given root directory (%~dp0) recursively and iterates through all items matching Export* (you might replace this pattern by Export or Exports, depending on your needs); the hierarchy depth is not checked in order to avoid the need of three nested loops. Anyway, if the iterated item is a directory, the sub-directory Excel is enumerated and searched for items matching *.xlsx.
Supplement:
The above command line may display many error messages like ERROR: The specified directory does not exist. or ERROR: Files of type "*.xlsx" not found., depending on your data; to avoid them, redirect STDERR to the nul device:
2> nul forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C echo 00x7840path0x22"
The forfiles command returns an empty line to STDOUT, so the above command line will contain many of them; to avoid such too, redirect STDERR and STDOUT to the nul device and redirect only the wished data to the console con:
1> nul 2>&1 forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C 1> con echo 00x7840path0x22"
You can send results with | to FINDSTR like this:
FORFILES /P . /S /M *.xlsx /D -365 /C "CMD /C ECHO #path" | ^
FINDSTR "\\Exports\\" | ^
FINDSTR /I /C:Delete /V
So you search every xlsx files located in a certain path (here is current dir) Every xlsx must contain Exports as folder and show every xlsx that doesn't (/V Displays only the non-matching lines) contain "delete" (/I mean insensitive)
In a batch file you can replace /P . by any variable path /P "%~dp0" /P "%CD%" or send as argument /P %1
Also you can do FOR loop to make any command for every match.
In one line to put in console:
FOR /F "usebackq delims=" %A in (`forfiles /p . /s /m *.xlsx /D -365 /C "cmd /c ECHO #path" ^|FINDSTR "\\Exports\\" ^|FINDSTR /I /C:Delete /V`) DO #ECHO FAKE-COMMAND %A
In a batch file:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "usebackq delims=" %%A in (
`forfiles /p . /s /m *.xlsx /D -365 /C "cmd /c ECHO #path" ^|FINDSTR "\\Exports\\" ^|FINDSTR /I /C:Delete /V`
) DO (
SET "myfile=%%~A"
#ECHO FAKE-COMMAND "!myfile!"
)
ENDLOCAL
GOTO :EOF

Resources