Windows batch script to download yesterday files

2019-05-27 12:07发布

问题:

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?

回答1:

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.



回答2:

It's a pretty complex task to implement with Windows batch-file and the built-in FTP client (ftp.exe).

It would be more easier with PowerShell.


And even easier using a more capable FTP client, like the latest version of WinSCP FTP client.

If you want to download files based on a pattern in a file name, this will do:

winscp.com /ini=nul /log=yesterday.log /command ^
    "open ftp://username:password@ftp.example.com/" ^
    "get /remote/path/*%%TIMESTAMP-1D#yyyy-mm-dd%%* C:\local\path\" ^
    "exit"

This uses the %TIMESTAMP% syntax


If you want to download based on a file modification time, use a file mask with a time-constraint:

winscp.com /ini=nul /log=yesterday.log /command ^
    "open ftp://username:password@ftp.example.com/" ^
    "get /remote/path/*>=yesterday<today C:\local\path\" ^
    "exit"

The >=yesterday<today syntax is supported by WinSCP 5.15 and newer.

In older versions of WinSCP, you can again use %TIMESTAMP% syntax, particularly >=%%TIMESTAMP-1D#yyyy-mm-dd%%<%%TIMESTAMP#yyyy-mm-dd%%, instead of >=yesterday<today.

(I'm the author of WinSCP)



回答3:

This is a sample FTP script that does almost exactly what you need but it uses a 3rd party client instead of the one that comes free with Windows: http://kb.robo-ftp.com/script_library/show/45

Maybe you can convert it.