DOS Batch FTP - Get New Files Only - Ftp script to download only files that don`t exist in local folder

This batch connects twice to the FTP server. First time it retrieves a list of files on the FTP server. This list is being trimmed to contain only files that don`t already exist locally. The files in the trimmed list are then downloaded during a second connection.  Note: Since all files are passed into the FTP`s MGET command there might be a limit to the number of files that can be processed at once.

@Echo Off

REM – Define File Filter, i.e. files with extension .txt
Set FindStrArgs=/E /C:”.txt”

REM – Extract Ftp Script to create List of Files
Set ”FtpCommand=ls”
Call:extractFileSection ”[Ftp Script 1]“ ”-”>”%temp%\%~n0.ftp”
Rem Notepad ”%temp%\%~n0.ftp”

REM – Execute Ftp Script, collect File Names
Set ”FileList=”
For /F ”Delims=” %%A In (’”Ftp -v -i -s:”%temp%\%~n0.ftp”|Findstr %FindStrArgs%”‘) Do (
Call Set ”FileList=%%FileList%% ”%%A“”
)

REM – Extract Ftp Script to download files that don’t exist in local folder
Set ”FtpCommand=mget”
For %%A In (%FileList%) Do If Not Exist ”%%~A“ Call Set ”FtpCommand=%%FtpCommand%% ”%%~A“”
Call:extractFileSection ”[Ftp Script 1]“ ”-”>”%temp%\%~n0.ftp”
Rem Notepad ”%temp%\%~n0.ftp”

For %%A In (%FtpCommand%) Do Echo.%%A

REM – Execute Ftp Script, download files
ftp -i -s:”%temp%\%~n0.ftp”
Del ”%temp%\%~n0.ftp”
GOTO:EOF

:extractFileSection StartMark EndMark FileName — extract a section of file that is defined by a start and end mark
::                  — [IN]     StartMark - start mark, use ‘…:S’ mark to allow variable substitution
::                  — [IN,OPT] EndMark   - optional end mark, default is first empty line
::                  — [IN,OPT] FileName  - optional source file, default is THIS file
:$created 20080219 :$changed 20081204 :$categories ReadFile
:$source http://www.dostips.com
SETLOCAL
set “bmk=%~1″
set “emk=%~2″
set “src=%~3″
set “bExtr=”
set “bSubs=”
if “%src%”==”" set src=%~f0&        rem if no source file then assume THIS file
for /f “tokens=1,* delims=]” %%A in (’find /n /v “” “%src%”‘) do (
if /i “%%B”==”%emk%” set “bExtr=”&set “bSubs=”
if defined bExtr if defined bSubs (call echo.%%B) ELSE (echo.%%B)
if /i “%%B”==”%bmk%”   set “bExtr=Y”
if /i “%%B”==”%bmk%:S” set “bExtr=Y”&set “bSubs=Y”
)
EXIT /b

[Ftp Script 1]:S
!Title Connecting…
open example.com
username
password

!Title Preparing…
cd public_html/MyRemoteDirectory
lcd c:\MyLocalDirectory
binary
hash

!Title Processing… %FtpCommand%
%FtpCommand%

!Title Disconnecting…
disconnect
bye

FOR Command Batch File

FOR %file_name IN (criteria) DO command

The %file_name is a variable that will contain the name of the current file being processed. These follow usual command line batch programming variable naming conventions; they start with a % (if used in a batch file), and can be any alpha value. They can not be the numbers 0 to 9, because these are reserved for the parameters fed to the batch file on the command line.

The criteria can be any wildcard-enabled search that can be issued using the DIR command in the command line environment. The following are all valid:

* *.*
* *.html
* 00_??.*

The command is any valid command including call with a batch file name to execute an external batch file, or an executable file name. So, to concatenate a list of text files, the following could be used:
echo > %2
for %%A in (%1) do type %%A >> %2

The above assumes that it is called with a command such as:

* concat_files *.txt output_file.txt

There are a few more options that can be used with file processing and the FOR command.

Using FOR to Process Lists of Files

The /D switch may be used between the FOR keyword and the variable name to limit the selection of files to folders. This might be useful in performing selective backups, for example. The /R switch can be used to walk the current directory tree. This will cause the command to recurse into each folder that it finds, and look for files that match the criteria.

If a path to a folder is supplied after the /R switch, then

Using FOR to as a Looping Construct

With the /L switch, it is possible to execute a command a given number of times based on a variable set that has a 1) start, 2) step and 3) end value. The command will loop through the values, starting at start adding step at each iteration, and then stopping when the current value is equal to, or greater than end. To loop forwards:

for /L %%A in (0, 1, 10) do echo %%A

It is also possible to loop backwards:
for /L %%A in (10,-1, 0) do echo %%A

And also, step by a different amount:
for /L %%A in (0, 2, 8) do echo %%A

Note that all that has happened in this usage is that the file set has been replaced by a numerical set of values.

Debugging FOR loops can be quite tricky, and so a good debugger such as the Running Steps IDE is useful for stepping through the code.

Semicolon is the default end-of-line (EOL) character used by the FOR command.

What Batch File Programming Can Be Used For

Batch file programming is a very useful way to automate small, repetitive, tasks. The Windows Command Line Programming tutorial is a good starting place to read about the basics of batch file programming, for those who are new to creating batch files.

It is also a good idea to have a debugger handy, such as the Running Steps batch file IDE and integrated debugger.

The FOR command has 2 uses in batch file programming:

* Processing lists of files;
* Looping through variable values.

In command line batch file programming, FOR works rather like other looping constructs common to all procedural programming languages. The difference between traditional FOR commands for counted loops is that, in MS-DOS/Windows Command Line Batch File programming, it can be used to process a list of files.

Attach Date/Time Stamp To A File - Can Be Used For Automated Backups

Here is an interesting one. I found a way to take the %date% environment variable, and turn it into a valid string for a filename - without any extra programs or scripts.

For the longest time I used a little utility I created to do this. The problem with that is the utility needs to be around if you want to send the batch file to someone.

What I didn’t know that was that you can use this character combination ‘:~’ to pull a substring out of an environment variable. That is when I realized you could use this to pull out parts of the current date (or time).

Here is how it works. Lets take the %date% variable and print it out

echo %date%

It comes back …At least today ;) .. with

Thu 02/15/2007

Not sure if the length of the day changes. It may be always the same. To be safe we can pull the year, month and day starting from the right.

The :~ substring command works like this:

:~[START POS],[LENGTH]

If [START_POS] is positive or zero the substring will start from the left. If the number [START_POS] is negative it will start from the right. And [LENGTH] is the number of characters in the opposite direction of the starting point.

I know this might be confusing at first, but you will see what I am talking about.

If we wanted to get the current year we could start 4 from the end, and 4 in length. Like this:

echo %date:~-4,4%

For the month we start 7 from the right (Length of Year + Length of Month + 1 Slash)

echo %date:~-7,2%

For the day we start 10 from the right (Length of Year + Length of Month + Length Of Day + 2 Slashes)

echo %date:~-10,2%

Bringing it all together. Lets say I zipped up a folder every night for archival purposes, and wanted a different filename for each day (Not sure if this pkzip syntax is correct, but that is not important for our discussion here)

pkzip c:\ImportantFolder\*.* c:\TempZip.zip

ren

C:\TempZip.Zip c:\TempZip_%date:~-4,4%%date:~-7,2%%date:~-10,2%.zip

Which renames our C:\TempZip.Zip to C:\TempZip_20070215.zip

Perfect.  I get a date stamped file, and no special vbscript, or command line program is needed.

The same method could be used for the current time

I am still amazed this little trick works.

Dated Directories Backup Using Batch File

In the example below, we first set 3 variables: drive, folder, and backupcmd. The “drive” variable defines the root directory of our backups. The “folder” takes the 2 digit day value from the current date (US date format, taking 2 digits from the date command output, starting at the 7th character), which we will use as a subdirectory. The third variable, “backupcmd” defines our backup command with the appropriate command line switches we want to use.

@echo off
:: variables
set drive=D:\Backup
set folder=%date:~7,2%
set backupcmd=xcopy /s /c /d /e /h /i /r /k /y

echo ### Backing up directory…
%backupcmd% “C:\Program Files\somedirectory” “%drive%\%folder%”

echo Backup Complete!
@pause

This example will backup the “C:\Program Files\somedirectory” folder to “D:\Backup\[dd]” where [dd] is the current day of the month. After a month, we will have 30ish daily copies of the backup… And, because of the xcopy command line switches chosen, following backups will only overwrite files that are newer, speeding up subsequent backups. Alternatively you can add a line to delete the %folder% directory prior to executing the %backupcmd% if you prefer to start clean (and take longer).

Notes:

* Any batch file can be interrupted with CTRL+C or CTRL+Break if needed.
* Instead of backing up My Documents, Favorites, Outlook and Outlook Express files separately, you can combine it all into one line for the current user: %backupcmd% “%USERPROFILE%” “%drive%\%UserName% - profile” . The only disadvantage being that it would save temporary IE files as well (however the default location of those can be changed).
* The Registry backup in the above example works well only for partial registry restores, it does not save the complete system state. Read this FAQ for more info.

Backup Using Batch File - Set Current Date as a Name of The Backup

Sometimes it is useful to create folders with the date incorporated in the folder name. Here is how to set the variable folder to the current date (assuming US system date format):

set folder=%date:~10,4%_%date:~4,2%_%date:~7,2%
%backupcmd% “…source dir…” “%drive%\%folder%\…destination dir…”

It is also possible to use the current time in the folder name. The following example with incorporate both the current date and time to the minute, separated by underscores. There is an extra step that cleans up possible spaces in single-digit hours in the system time:

set hour=%time:~0,2%
if “%hour:~0,1%”==” ” set hour=0%time:~1,1%
set folder=%date:~10,4%_%date:~4,2%_%date:~7,2%_%hour%_%time:~3,2%
%backupcmd% “…source dir…” “%drive%\%folder%\…destination dir…”

Backing up Directories and networked PCs using Batch File

You can backup other directories by simply creating more alike lines:

%backupcmd% “…source dir…” “%drive%\…destination dir…”

For example, if you’d like to backup “C:\Program Files\Microsoft Office” to our destination “G:\Backup\MS Office” (and retain the directory structure) you’d need to add the following line to the batch file:

%backupcmd% “C:\Program Files\Microsoft Office” “%drive%\MS Office”

Here is another example, backing up the Administrator Profile on a machine on the LAN with computer name “Lianli”:

%backupcmd% “\UserProfile\c\Documents and Settings\Administrator”  “%drive%\UserProfile - admin profile”

Remember, you have to save the batch file with either .bat or .cmd extension, then just double-click to execute it.

Backup “My Documents”, Favorites, Outlook Express email/address book, (all for the current user) and the Windows Registry Using Batch File

Sometimes it is useful or even necessary to simply copy existing directories to another hard disk or network drive rather than using more complicated backup methods. Multiple directories can be backed up comparatively easy with a simple click by creating and running a batch file. That file can be executed manually from your desktop, can be added to startup or scheduled for periodic execution as needed.

Batch files have comparatively easy syntax and can have many uses so this method could also be a good learning experience by example. You can simply copy the text below, and paste it into Notepad. Create a new file with either .bat or .cmd extension, rather than as a .txt file.

Here is a working example of a backup script you can modify for your needs:

@echo off
:: variables
set drive=g:\Backup
set backupcmd=xcopy /s /c /d /e /h /i /r /k /y

echo ### Backing up My Documents…
%backupcmd% “%USERPROFILE%\My Documents” “%drive%\My Documents”

echo ### Backing up Favorites…
%backupcmd% “%USERPROFILE%\Favorites” “%drive%\Favorites”

echo ### Backing up email and address book (Outlook Express)…
%backupcmd% “%USERPROFILE%\Application Data\Microsoft\Address Book” “%drive%\Address Book”
%backupcmd% “%USERPROFILE%\Local Settings\Application Data\Identities” “%drive%\Outlook Express”

echo ### Backing up email and contacts (MS Outlook)…
%backupcmd% “%USERPROFILE%\Local Settings\Application Data\Microsoft\Outlook” “%drive%\Outlook”

echo ### Backing up the Registry…
if not exist “%drive%\Registry” mkdir “%drive%\Registry”
if exist “%drive%\Registry\regbackup.reg” del “%drive%\Registry\regbackup.reg”
regedit /e “%drive%\Registry\regbackup.reg”

:: use below syntax to backup other directories…
:: %backupcmd% “…source directory…” “%drive%\…destination dir…”

echo Backup Complete!

@pause

The above example backs up “My Documents”, Favorites, Outlook Express email/address book, (all for the current user) and the Windows Registry. It copies the files to the directory defined in the %drive% variable, or “g:\Backup”. If the script is run multiple times, it will only rewrite if the source files are newer. It will create subdirectories as necessary, and it will retain file attributes. It can copy system and hidden files.

In the above file, all lines that begin with “::” are comments. The “set drive=” and “set backupcmd=” near the top define two variables (referenced by %drive% and %backupcmd%), used a number of times throughout the file; the first being the location of the top directory where we want to backup, and the second the actual copy command with all necessary switches. All the “echo ” lines in the file simpy output the line of text to the screen, and the lines beginning with %backupcmd% are the actual commands to execute.

Note that most of the folders in the above backup example are subdirectories of the %USERPROFILE%… It is possible to simply backup the entire user profile with My Documents, Favorites, Outlook Express, Outlook, etc. by backing up this one folder. Here is an example (it assumes the above “drive” and “backupcmd” variables are set):

%backupcmd% “%USERPROFILE%” “%drive%\%UserName% - profile”

Batch file that downloads files from FTP server on Windows Scheduler

Batch file that can be run from windows scheduler to download two files from my server via ftp. I have username password address location of the file and filename.

V@echo off

> %0.ftp echo o mysite.com
>> %0.ftp echo username
>> %0.ftp echo password
>> %0.ftp echo bin
>> %0.ftp echo cd mydir
>> %0.ftp echo prompt
>> %0.ftp echo mget filename.ext
>> %0.ftp echo bye

ftp -s:%0.ftp

Searching for a string of text in a MS-DOS batch file

Using the findstr command will enable you to search for text within any plaintext file. Using this command within a batch file will allow you to search for text and create events off the results found. Below are some examples.

Basic search

In the below example this basic batch file would search through the hope.txt file for the string “computerhope” and if found echo back to the screen “There is hope!”.

@echo off
findstr /m “computerhope” hope.txt
if %errorlevel%==0 (
echo There is hope!
)

Log results and wildcards

In the below example this batch file searches for computerhope in any txt file in the current directory using the wildcards *.txt then prints the files containing this string into the results.txt file. In addition, this batch file also has an else statement that will print if no matches were found.

Note: When doing the else it *must* follow the close parenthesis, so it must be “) else (” otherwise you’ll get the ‘else’ is not recognized as an internal or external command, operable program or batch file.” error.

@echo off
findstr /m “computerhope” *.txt > results.txt
if %errorlevel%==0 (
echo Found! logged files into results.txt
) else (
echo No matches found
)