如何从FTP服务器上的通配符文件夹中自动下载特定文件类型

时间:2017-11-06 18:54:18

标签: batch-file ftp winscp

我试图设置一种方法来自动下载ftp服务器上的所有.mkv文件,在这个文件夹中我不知道全名。我将要知道的最多的是The.Walking.Dead。*哪里的星代表我不知道的文件夹名称。目前我使用的是WinSCP,我从这里得到的最接近的代码是

@echo off

"C:\Program Files (x86)\WinSCP\WinSCP.com" ^
  /log="D:\Documents\WinSCP Log\WinSCP.log" /ini=nul ^
  /command ^
    "open "ftp://ivay.myseedbox.site/downloads/manual/" ^
    get "/The.Walking.Dead.*/*.mkv" "E:\Torrents\TV Shows\The Walking Dead\Season 8\" ^
    PAUSE
    exit

set WINSCP_RESULT=%ERRORLEVEL%
if %WINSCP_RESULT% equ 0 (
  echo Success
) else (
  echo Error
)

exit /b %WINSCP_RESULT%

但是这会返回错误

< 2017-11-06 12:47:02.172 Script: No file matching 'The.Walking.Dead.*' found.
. 2017-11-06 12:47:02.172 Listing file "E:\Torrents\TV".
. 2017-11-06 12:47:02.172 Retrieving file information...
> 2017-11-06 12:47:02.172 PWD
< 2017-11-06 12:47:02.308 257 "/"
> 2017-11-06 12:47:02.308 CWD /downloads/manual/E:\Torrents\TV
< 2017-11-06 12:47:02.433 550 Failed to change directory.
> 2017-11-06 12:47:02.433 TYPE I
< 2017-11-06 12:47:02.557 200 Switching to Binary mode.
> 2017-11-06 12:47:02.557 SIZE /downloads/manual/E:\Torrents\TV
< 2017-11-06 12:47:02.681 550 Could not get file size.
. 2017-11-06 12:47:02.681 Could not retrieve file information
< 2017-11-06 12:47:02.681 Script: Can't get attributes of file 'E:\Torrents\TV'.
< 2017-11-06 12:47:02.681 Could not retrieve file information

< 2017-11-06 12:47:02.681 Could not get file size.
. 2017-11-06 12:47:02.681 Script: Failed

所以我可以看到它正在尝试获取我的文件夹目录并将其用作文件路径,同时忽略本地目录中的空间并将远程和本地目录压缩在一起。所以任何帮助都会受到赞赏,因为我几乎不知道这里发生了什么。

2 个答案:

答案 0 :(得分:1)

选择要传输的文件时,file mask只能用于路径的最后一个组件。

你可以做的一件事是:

get -filemask=*.mkv /The.Walking.Dead.* "E:\Torrents\TV Shows\The Walking Dead\Season 8\"

但是这将重新创建匹配文件夹(The.Walking.Dead.*)作为目标本地文件夹(Season 8)的子文件夹。

如果要将文件(*.mkv)直接下载到目标本地文件夹(Season 8),可以让WinSCP将源文件夹“重命名”为Season 8

get -filemask=*.mkv /The.Walking.Dead.* "E:\Torrents\TV Shows\The Walking Dead\Season 8"

请注意目标路径中没有尾部反斜杠。它使WinSCP将匹配的源文件夹(The.Walking.Dead.*)下载到名为The Walking Dead的目标本地文件夹(Season 8,而不是Season 8!)。由于Season 8已经存在,它不会对它做任何事情,并会直接继续下载所包含的文件。

以前适用于您的具体案例。在更复杂的情况下,您需要在下载之前找到该文件夹​​的名称。虽然使用普通批处理文件实现这一点并非不可能,但它会非常复杂。

在这种情况下,我建议使用PowerShell并使用WinSCP .NET assembly

有了它,脚本(例如download.ps1)就像:

# Set up session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "ftp.example.com"
    UserName = "username"
    Password = "password"
}

Write-Host "Connecting..."
$session = New-Object WinSCP.Session
$session.SessionLogPath = "session.log"
$session.Open($sessionOptions)

$remotePath = "/"
$localPath = "C:\local\path"
$pattern = "The.Walking.Dead.*"
$twdFolder =
    $session.ListDirectory($remotePath).Files |
    Where-Object { $_.IsDirectory -and ($_.Name -like $pattern) } |
    Select-Object -First 1

if ($twdFolder -eq $Null)
{
    Write-Host "No folder matching '$pattern' found."
}
else
{
    Write-Host "Found folder '$($twdFolder.Name)', downloading..."
    $sourcePath = [WinSCP.RemotePath]::CombinePaths($remotePath, $twdFolder.Name)
    $sourcePath = [WinSCP.RemotePath]::CombinePaths($sourcePath, "*")
    $destPath = Join-Path $localPath "*"
    $transferResult = $session.GetFiles($sourcePath, $destPath).Check()
}

Write-Host "Done"

Extract WinSCP automation package以及脚本和run the script类似:

powershell.exe -ExecutionPolicy Unrestricted -File download.ps1

答案 1 :(得分:0)

我完全忘了我发布在这里并最终弄清楚如何自己做。很抱歉不回复任何人。我非常感谢你花时间帮助我,我完全忘了它。可能不是最干净的方法,但它对我有用lol。我有点想添加一个下载进度条,但我觉得这会非常复杂。这就是我最终使用的:

param (
    $localPath = "E:\Torrents\TV Shows\The Walking Dead\Season 8\",
    $remotePath = "/downloads/manual/The.Walking.Dead.*",
    $fileName = "*"
)

    # Deletes new episode folder just in case one exists 
    Remove-Item "E:\Torrents\TV Shows\The Walking Dead\Season 8\New Episode" -recurse -EA SilentlyContinue

    #Tells the user that the files are being downloaded
    cls
    "Downloading The Walking Dead. This can take a while."
    "Please do not close this window."

try
{
# Load WinSCP .NET assembly
Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"

# Set up session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "removed"
    PortNumber = 21
    UserName = "removed"
    Password = "removed"
}

$session = New-Object WinSCP.Session

try
{
    # Connect
    $session.Open($sessionOptions)

    # Download the file and throw on any error and deletes the files from  the server
    $session.GetFiles(
        ($remotePath + $fileName),
        ($localPath + $fileName))
    $session.RemoveFiles("/downloads/manual/The.Walking.Dead.*")
}

finally
{
    $session.Dispose()
}

    # Renames the downloaded folder
    Rename-Item "E:\Torrents\TV Shows\The Walking Dead\Season 8\The.Walking.Dead.*" "New Episode" -EA SilentlyContinue

    # Deletes unnecesary files
    Remove-Item "E:\Torrents\TV Shows\The Walking Dead\Season 8\New Episode\*" -exclude *.mkv -EA SilentlyContinue

    # Moves video file to proper directory
    Move-Item "E:\Torrents\TV Shows\The Walking Dead\Season 8\New Episode\*.mkv" "E:\Torrents\TV Shows\The Walking Dead\Season 8" -EA SilentlyContinue

    # Deletes new episode folder to clean things up
    Remove-Item "E:\Torrents\TV Shows\The Walking Dead\Season 8\New Episode" -recurse -EA SilentlyContinue

    exit 0
}
catch [Exception]
{
    Write-Host "Error: $($_.Exception.Message)"
    exit 1
}