Folder Monitoring with Batch File - batch-file

I want to monitor my folder if new file added or not. Then If added I would like to execute some files. But I don't want to use third party app.
I have some ideas but I don't know how to do that.
This is my folder; D:\MonitoringFolder
So every hour batch file will check the files inside of it and writes them into a txt.
dir /b "D:\MonitoringFolder" > old.txt
Old.txt is --> string 1 , string 2, string 3
After one hour, batch file will check it later and writes again into another txt.
dir /b "D:\MonitoringFolder" > new.txt
New.txt is --> string 1, string 2, string 3, string 5
Then it will compare new.txt and old.txt. So string 5 added recently. It will prompt a window and says "String 5" added!. Or new file added (removed).
I want to do that If someone could show me a way to do this I would appreciate that.

Script MONITOR.cmd scheduled to run every now and then:
IF EXIST NEW.TXT DEL NEW.TXT
FOR /F "tokens=*" %%* IN ('DIR /S /B /ON "D:\MonitoringFolder"') DO ECHO "%%*">>NEW.TXT
FOR /F "tokens=*" %%* IN (NEW.TXT) DO (FIND %%* OLD.TXT >NUL || START CMD /K INSERTED.cmd %%*)
FOR /F "tokens=*" %%* IN (OLD.TXT) DO (FIND %%* NEW.TXT >NUL || START CMD /K DELETED.cmd %%*)
DEL OLD.TXT
REN NEW.TXT OLD.TXT
Script INSERTED.cmd will create new window prompting for action on appearing of a new file:
ECHO Inserted new file %1
DIR %1
PAUSE & EXIT
Script DELETED.cmd will create new window prompting for action on disappearing of an old file:
ECHO Deleted file %1
PAUSE & EXIT
Subfolders are monitored, too. It worked for me even with spaces and accented characters in filename.

Since you're already dumping the output every hour, just execute this command from the prompt:
fc /u old.txt new.txt
It will tell you, if any, which differences exist between the two files.

Maybe you're going to write batch scripts (for scanning folder and compare results) and schedule them with a scheduler like cron (Linux) or windows task scheduler every hours for e periodical checking. Some documents here : http://support.microsoft.com/kb/308569 , http://code.tutsplus.com/tutorials/scheduling-tasks-with-cron-jobs--net-8800

#ECHO OFF &SETLOCAL disableDelayedExpansion
SET "SaveFile=Save.File"
IF NOT EXIST "%SaveFile%" GOTO:cont
DIR /b /a-d | FINDSTR /vg:"%SaveFile%">nul||EXIT /b
ECHO(execute some programs here
:cont
>"%SaveFile%" DIR /b /a-d

Related

Why does a batch file working before not work anymore as expected on some machines?

I have a batch script already working for some months. The purpose of the script is to create a folder based on the file name and rename the folder accordingly for a certain purpose. However, it stops moving the files to the created folder in the loop. I tested it on other machine and it was working fine, but on a particular machine; it is just not working.
What can I do to make the loop effective and why did the batch stop working (moving files to folder) after working for many months now?
setlocal EnableDelayedExpansion
for /F %%a in ('dir "C:\Program Files\WinSCP\Unconverted" /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :func "%%~a"
:func
set file=%~1
set dir=%file:~0,49%
mkdir "C:\Program Files\WinSCP\Unconverted\%dir%_fdc" 2>nul
rem ECHO "%file%"
rem ECHO "C:\Program Files\WinSCP\Unconverted\%dir%_fdc"
move /Y "C:\Program Files\WinSCP\Unconverted\%file%" "C:\Program Files\WinSCP\Unconverted\%dir%_fdc"
)
start "" "C:\Program Files\WinSCP\hide_conversion_window.exe"
I rewrote and commented the batch file as it contains several issues whereby most were not problematic as long as this batch file is stored in %ProgramFiles%\WinSCP\Unconverted and this directory is also the current directory on execution of the batch file as on double clicking the batch file.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=%ProgramFiles%\WinSCP\Unconverted"
rem Process all files in source folder found by command DIR with ignoring
rem subfolders and listed in bare format which means only file names with
rem file extension but without file path. The batch file itself is skipped
rem if being also stored in the source folder specified above.
for /F "delims=" %%I in ('dir "%SourceFolder%\*" /A-D /B 2^>nul') do (
if /I not "%SourceFolder%\%%I"=="%~f0" call :MoveFile "%SourceFolder%\%%I"
)
rem Execute converter through AutoIt in a separate command process and
rem while conversion is running continue with batch processing which means
rem restoring previous environment and finally exiting batch file processing.
start "" "%ProgramFiles%\WinSCP\hide_conversion_window.exe"
endlocal
goto :EOF
rem MoveFile is a subroutine which expects to be called with one argument
rem being the name of the file to move with full file name which means
rem with file path, file name and file extension.
rem The first 49 characters of the file name define the name for target
rem folder on which "_fdc" must be appended for completion. This folder
rem is created without verification on success and then the file is
rem moved into this folder again without verification on success.
:MoveFile
set "FileName=%~nx1"
set "FolderName=%FileName:~0,49%_fdc"
mkdir "%~dp1\%FolderName%" 2>nul
move /Y "%~1" "%~dp1\%FolderName%\" >nul
goto :EOF
This batch file works for batch file being stored in a different folder than source folder or current directory is a different directory than the folder containing the batch file or a found file contains a space character or any other special character like &()[]{}^=;!'+,`~.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
mkdir /?
move /?
set /?
setlocal /?
start /?
Read also the Microsoft article about Using Command Redirection Operators.
Thanks for the suggestion oldabi. Sometimes things do work and we are thinking is all perfect until it breaks down. Thanks for the suggestion. I just realised my mistake about missing bracket.
SETLOCAL ENABLEDELAYEDEXPANSION
for /F %%a in ('dir "C:\Program Files\WinSCP\Unconverted" /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :func "%%~a" )
goto conversion
:conversion
rem ::execute converter through autoit
start "" "C:\Program Files\WinSCP\hide_conversion_window.exe"
:func
set file=%~1
set dir=%file:~0,49%
mkdir "C:\Program Files\WinSCP\Unconverted\%dir%_fdc" 2>nul
rem ECHO "%file%"
rem ECHO "C:\Program Files\WinSCP\Unconverted\%dir%_fdc"
MOVE /Y "C:\Program Files\WinSCP\Unconverted\%file%" "C:\Program Files\WinSCP\Unconverted\%dir%_fdc"

Batch file to copy the first PDF in multiple folders from c:\pdf\ to single folder c:\qa\

I have hundreds of sub folders coming off a c:\pdf\ folder.
I want to take the first pdf (sorted by name) in each sub folder and copy them to a single folder, say c:\QA\ so I can check the PDF for errors manually.
Can anyone help? Please!
I have this so far:
#echo off
cls
cd c:
cd c:\pdf\
for /r %%a in (*.pdf) do (
copy %%a c:\qa\%%~nxa
GOTO :EXIT
)
:Exit
Note File names are unique. Target dir is never a subdir of source. The baove code works for the first pdf in a sub folder but does not do the rest of the sub folders.
The New Technology File System (NTFS) returns a list of file names matching a wildcard pattern always sorted in alphabetical order. So for NTFS formatted partitions the following batch code is perhaps enough for this task.
#echo off
for /D %%D in ("C:\pdf\*") do if exist "%%D\*.pdf" call :CopyFirstFile "%%D"
goto :EOF
:CopyFirstFile
for %%F in ("%~1\*.pdf") do (
copy "%%F" C:\qa\
goto :EOF
)
goto :EOF
Please note that first FOR ignores subfolders with hidden attribute set. And the second FOR in subroutine CopyFirstFile ignores PDF files with hidden attribute set.
Another solution working also for File Allocation Table (FAT) partitions (FAT16, FAT32, exFAT) uses the command DIR to get the list of *.pdf files sorted by name.
#echo off
for /D %%D in ("C:\pdf\*") do if exist "%%D\*.pdf" call :CopyFirstFile "%%D"
goto :EOF
:CopyFirstFile
for /F "delims=" %%F in ('dir /A-D /B /ON "%~1\*.pdf"') do (
copy "%~1\%%F" C:\qa\
goto :EOF
)
goto :EOF
The command DIR ignores directories matching the pattern *.pdf and finds also hidden *.pdf files because of option /A-D. But COPY does not copy a hidden *.pdf file!
It would be perhaps better to use MOVE instead of COPY as on next run the batch file would copy the same files again if the folders in C:\pdf are not modified in the meantime.
The command lines below label CopyFirstFile are interpreted as subroutine called by the first FOR loop.
The first goto :EOF exits batch file processing once the first FOR loop iterating over all non hidden subdirectories of C:\pdf finished.
The second goto :EOF exits the second FOR loop and the subroutine after copying the first file found in the directory passed as first (and only) argument to the subroutine.
The third goto :EOF would not be really necessary as this command line should be never executed and is additionally also not needed when there are no more command lines in the batch file. But it is good practice to make sure that each block called as subroutine has as last line goto :EOF or alternatively exit /B which is exactly the same as goto :EOF.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
copy /?
dir /?
echo /?
for /?
goto /?
if /?
Here's some example code for you. It looks inside each directory and any potential subdirectory below C:\PDF, it does not look at files inside C:\PDF. If you're looking for something different then update your question accordingly.
#Echo Off
For /D /R "C:\PDF" %%A In (*) Do (
For /F "Delims=" %%B In ('Dir/B/A-D/O-N "%%A\*.pdf" 2^>Nul') Do (
Set "first=%%A\%%B")
SetLocal EnableDelayedExpansion
If Exist "!first!" Copy "!first!" "C:\QA"
EndLocal)
Pause
Please don't just use it, take your time to learn it by checking various references as well.
All you need to do is to combine the features of Dir & For . Now, You can simply analyze the code and modify it according to your need.
Hint for the Code:
CD /D "C:\PDF"
DIR /s /b *.pdf >a.txt
For /f "Tokens=*" %%A In (a.txt) Do (Copy /Y "%%A" "C:\QA")
Exit
And, it is almost all you need. :)

list date created and file name for all files in subdirectories

I am currently using the following line in my batch file to retrieve a list of pdf files in my subdirectory that contain the word "complete" in the title.
dir /b /s *COMPLETE*.PDF >Q:\"Personal Folders"\Advertising\"Data Updates"\ePrint\test.csv
Is there a way that I can change this to append the date created to the beginning of each file so that I can sort them by date in excel? Thank you.
How do I append the date created to the beginning of each file name?
Use the following batch file.
GetFileCreateDate.cmd:
#echo off
setlocal
for /f "tokens=*" %%f in ('dir /b /s "*COMPLETE*.PDF"') do (
for /f "tokens=1,2" %%g in ( 'dir "%%f" /tc ^| findstr /C: "%%~nxf"') do (
echo %%g,%%h,"%%f"
)
)>>Q:\"Personal Folders"\Advertising\"Data Updates"\ePrint\test.csv
endlocal
Notes:
Output lines will have the format:
create_date,create_time,"filename"
Where filename is the absolute name of the file
Modify echo %%g,%%h,"%%f" to suit the format you want in your csv file.
%%g is the create_date, %%h is the create_time and %%f is the absolute filename.
Example output (writing to just "test.csv"):
F:\test>dir /b /s "*COMPLETE*.PDF"
F:\test\1complete1.pdf
F:\test\2complete2.pdf
F:\test\complete1.pdf
F:\test\complete2(s).pdf
F:\test>GetFileCreateDate.cmd
F:\test>type test.csv
26/08/2016,21:28,"F:\test\1complete1.pdf"
26/08/2016,21:28,"F:\test\2complete2.pdf"
26/08/2016,21:28,"F:\test\complete1.pdf"
26/08/2016,21:28,"F:\test\complete2(s).pdf"
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
dir - Display a list of files and subfolders.
findstr - Search for strings in files.
for /f - Loop command against the results of another command.
Next code snippet lists last written date & time and file paths:
>"Q:\Personal Folders\Advertising\Data Updates\ePrint\test.csv" (
for /F "delims=" %%G in ('dir /b /s *COMPLETE*.PDF') do echo %%~tG "%%~G"
)
Resources (required reading):
(command reference) An A-Z Index of the Windows CMD command line
(additional particularities) Windows CMD Shell Command Line Syntax
(%~tG etc. special page) Command Line arguments (Parameters)
(>, special page) Redirection

Creating Batch File to search .txt files in a specific folder for a specific string, and move all files to a new folder

Just as the title mentions, I am looking for a way to create a batch file which looks for a specific string in .txt files in a folder on my C drive. Any txt files that contain this string then need to be moved to a different folder.
I can get my batch file to find the items, I just can't figure out how to move all text files which contain the string.
Update: I am now able to get the files to move, with the use of the solution, provided below.
Thanks
Basically what you need to do is capture the output from a command. That is done with the FOR /F command.
FOR /F "delims=" %%G in ('findstr /m /C:"Thread aborted" *.txt') do (
move "%%G" C:\backup\
echo %%G>>logfile.txt
)
Just to show you that this does work. I am running everything from the command line to show you the output.
C:\BatchFiles\Tyler>echo Thread aborted>file.txt
C:\BatchFiles\Tyler>dir /b
backup
file.txt
C:\BatchFiles\Tyler>FOR /F "delims=" %G in ('findstr /m /C:"Thread aborted" *.*') do #move "%G" backup
1 file(s) moved.
C:\BatchFiles\Tyler>dir /b
backup
C:\BatchFiles\Tyler>dir /b backup\*.*
file.txt
C:\BatchFiles\Tyler>
Save this script to sorting.bat, run from open Cmd Prompt, and let me know if any errors. Based on your question, you seems to have no dir structure to bypass in the folder with target files. This code will also help users, who run a similar task and need to look through dir structure:
#echo off
set "sourcedir=C:/Provider.Rates" & set "destindir=C:/Aborted.Threads"
for /R "%sourcedir%" %%G in (*.txt) do (
find /i "Thread Aborted" "%%G" >nul 2>&1 && move /y "%%G" "%destindir%\%%~nxG" >nul)
echo/ & echo Sorting completed.
timeout 5
exit /b

Loop Through Files - Use Directory Name

TL;DR: I want to be able to loop through each file in a folder / subfolders and use the directory name the file is in, in each loop.
If I had a directory structure like:
-- Main
----- Printer 1
------- File 1
------- File 2
----- Printer 2
------- File 1
Ideally what I need to do is loop through 'Main' and get the files in 'Printer 1' and 'Printer 2', but I need to use the name of the printer directories in the script. Eg:
At the moment I'm using the below:
:loop
for /f %%f in ('dir /b D:\FireflyWebApps\www\apps\label\resources\labels_to_print\') do (
"C:/Program Files/Java/jre1.8.0_66/bin/java" -jar C:\test\pdfbox.jar PrintPDF -silentPrint D:\FireflyWebApps\www\apps\label\resources\labels_to_print\%%f
del D:\FireflyWebApps\www\apps\label\resources\labels_to_print\%%f
)
ping localhost -n 5 > nul
goto loop
Which works well, it loops trough the directory and prints the PDF's, but I need this to work with multiple printers. I know it's not an ideal solution, but I need to change the default printer to the 'Printer X' file names ( so I'll store the printer name as the folder, then run the change default printer command using it ).
How can I use the folder name the file is in, in the batch script?
Possible Solution
The below script will cd to the directory, loop through the directories in it, performing the inner loop on each one. Before it runs the inner loop, it gets the directory name and sets the default printer. I had to do an IF == 1 as it's a printer and I can't use '\' in folder name.
cd C:\test
for /D %%d in (*) do (
IF "%%d" == "1" (
RUNDLL32 PRINTUI.DLL,PrintUIEntry /y /n "\\192.168.102.131\lp1"
)
for /f %%f in ('dir /b C:\test\%%d') do (
echo %%f
)
)
pause
Here is my solution to your problem of getting folder name of a file:
#echo off
setlocal EnableDelayedExpansion
:loop
for /F "delims=" %%F in ('dir /A-D /B /S "D:\FireflyWebApps\www\apps\label\resources\labels_to_print\*" 2^>nul') do (
set "FolderPath=%%~dpF"
set "FolderPath=!FolderPath:~0,-1!"
for %%P in ("!FolderPath!") do (
echo Printer name is: %%~nxP
"%ProgramFiles%\Java\jre1.8.0_66\bin\java.exe" -jar C:\test\pdfbox.jar PrintPDF -silentPrint "%%F"
del "%%F"
)
)
ping localhost -n 5 > nul
goto loop
Command DIR with the options /A-D /B /S returns a list of all file names with full path without double quotes from specified directory and all subdirectories.
Drive and path with a backslash at end is assigned to an environment variable. The backslash at end must be removed which is done with a string substitution copying folder path string with exception of last character.
This folder path now without backslash at end is used in a second FOR loop which of course has always only 1 loop run to get with %%~nxP the name of the folder in which current file is stored which is the printer name.
The batch file as is just outputs the printer name.
Delayed variable expansion must be used here because of FolderPath being defined within a block.
Command DIR outputs an error message if it can't find any file in any directory. This error message is redirected from stderr to nul as of no interest for this batch file running continuously.
An alternate method without using command DIR working also for Unicode file names (© Joey):
#echo off
setlocal EnableDelayedExpansion
:loop
for /R "D:\FireflyWebApps\www\apps\label\resources\labels_to_print" %%F in (*) do (
set "FolderPath=%%~dpF"
set "FolderPath=!FolderPath:~0,-1!"
for %%P in ("!FolderPath!") do (
echo Printer name is: %%~nxP
"%ProgramFiles%\Java\jre1.8.0_66\bin\java.exe" -jar C:\test\pdfbox.jar PrintPDF -silentPrint "%%F"
del "%%F"
)
)
ping localhost -n 5 > nul
goto loop
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
dir /?
echo /?
for /?
goto /?
ping /?
set /?
setlocal /?

Resources