Q:

Windows batch script to download yesterday files

I am writing a script using ftp.exe to download files from an FTP server, it works at first. But the version I wrote was suited for only one file and the current date. My script is below:
echo user>>ftp.txt
echo password>>ftp.txt
set prefix=%date:~0,10%
set "name=%prefix%.txt"
echo get %name% >> ftp.txt
echo bye >> ftp.txt
ftp -s:ftp.txt ftpserver.com
del ftp.txt

But now there are more than one file named like aa-bb-2011-09-13.0.log,
aa-bb-2011-09-13.1.log,
aa-bb-2011-09-13.10.log. The last number is a serial number, it could be 0, 1, 2, 3...
How could download these files by batch script? How to modify my script to download more than one file (the number is unknown) which file name pattern is yesterday?

A:

In terms of downloading multiple files, use mget instead of get. The former allows you to specify wildcards for getting rather than specific files.
You'll just have to construct the "name" with a wildcard pattern, and make sure you have a prompt in your script before mget otherwise it will ask for confirmation on every file.
This is untested, but it's probably as simple as changing:
echo get %name% >> ftp.txt

to something like:
echo prompt>>ftp.txt
echo mget *%prefix%*>>ftp.txt

In terms of getting yesterdays date, you can use the following script. It's pretty complex compared to what you would do in, for example bash, but it works.
@setlocal enableextensions enabledelayedexpansion
@echo off

rem Get the date from WMI (on one line).

for /f "skip=2 tokens=2-7 delims=," %%A in ('wmic 
        path win32_localtime get day^,month^,year^ /format:csv') do (
    set /a "yest_yyyy = %%C"
    set /a "yest_mm = %%B"
    set /a "yest_dd = %%A"
)

rem Not the first of the month, just decrement day.

if not %yest_dd%==1 (
    set /a yest_dd = yest_dd - 1
    goto done
)

rem Jan 1, set to Dec 31 previous year.

if %yest_mm%==1 (
    set /a "yest_dd = 31"
    set /a "yest_mm = 12"
    set /a "yest_yyyy = yest_yyyy - 1"
    goto :done
)

rem Any other day, decrement month.

set /a "yest_mm = yest_mm - 1"

rem Need to find last day, default to 31.

set dim=31

rem Apr/Jun/Sep/Nov all have 30 days. Feb gets special handling.

if %yest_mm%==4 set dim=30
if %yest_mm%==6 set dim=30
if %yest_mm%==9 set dim=30
if %yest_mm%==11 set dim=30
if not %yest_mm%==2 goto :got_dim

rem Default Feb to 28 then use rules to override.

set dim=28

set /a "divid=yest_yyyy%%400"
if "%divid%"=="0" goto daysinmonth_29days
set /a "divid=yest_yyyy%%100"
if "%divid%"=="0" goto :done
set /a "divid=yest_yyyy%%4"
if not "%divid%"=="0" goto :done

rem Adjust to 29 days.

:daysinmonth_29days

set dim=29

:done

rem Pad out and return value.

if %yest_mm% lss 10 set yest_mm=0%yest_mm%
if %yest_dd% lss 10 set yest_dd=0%yest_dd%

set yesterday=%yest_yyyy%-%yest_mm%-%yest_dd%

endlocal && set yesterday=%yesterday%

It will set the yesterday environment variable to the format YYYY-MM-DD so that you can use it in your current script. Simply invoke call yesterday.cmd and then use the environment variable.

