0

我构建了一个脚本,它读取 CSV 文件以获取文件列表,然后将它们上传到 FTP 服务器。CSV 结构是这样的:

local_file,remote_file

该脚本会创建一个包含所有必要 FTP 命令的文本文件,然后运行 ​​FTP 命令。一切正常,除了 for 循环执行它的命令之外的代码,即,下面的所有echo put "%1" "%2" >> %Commands%内容也在每个 for 循环上执行,而不是得到一个包含所有 put 命令的格式良好的文件,我得到了这个(来自命令文件输出):

open servername 
username 
password 
binary 
put "local_path_to\first_file_on_the_list.php" "remote_path_to\first_file_on_the_list.php" 
close 
bye   
put "-d" "-i" 
close 
bye   
put "-d" "-i" 
close 
bye   
put "-d" "-i" 
close
...

这是脚本代码:

@echo off
setlocal EnableExtensions

rem Connection credentials
set Server=servername
set UserName=username
set Password=password

set Commands="commands.txt"
echo open %Server% > %Commands%
echo %UserName% >> %Commands%
echo %Password% >> %Commands%
echo binary >> %Commands%

rem Read the CSV file line by line
for /f %%a in (matches3.csv) do call :parse %%a

rem Transform CSV line into FTP put commmand
:parse
echo put "%1" "%2" >> %Commands%

:end
rem Add commands to close ftp conn
echo close >> %Commands%
echo bye   >> %Commands%

rem Perform the FTP upload
echo loggin in to ftp...
FTP -d -i -s:%Commands% %Server%
echo finished.
pause

rem Clean up.
if exist %Commands% del %Commands%
endlocal
exit

我不明白为什么下面的一切 :end 都被执行了!非常感谢您提前

4

3 回答 3

2

为什么下面的代码不应该:end执行?您永远不会在脚本中添加任何内容来结束 :parse 例程。

第一个 ewall 答案应该几乎可以工作,除了你需要一个 GOTO :END 在 FOR 语句之后。我看不出正确实施他的建议会如何导致无限循环。

另一种选择是在您的 EXIT 语句之后简单地移动您的子例程。

你还有其他隐藏的问题。文件路径/名称可以包含空格,因此默认的 FOR 分隔符空格,制表符将不会保留整行,如果有空格。默认的 EOL 也会导致任何以 开头的行;被忽略。这是一个潜在(但不太可能)的问题,因为有效的文件名可以以;.

解决方案是将 EOL 设置为无法开始有效文件规范的字符,并将 DELIMS 设置为空:"EOL=: DELIMS="

将所有文件写入行括在括号中并仅重定向一次输出会更有效。它也更容易编写并且看起来更好。

编辑 - 原始脚本试图在 ftp 脚本和 ftp 命令行中连接到服务器。一个或另一个必须被删除。我从 ftp 脚本中删除了它。

@echo off
setlocal EnableExtensions

rem Connection credentials
set Server=servername
set UserName=username
set Password=password

set Commands="commands.txt"
(
  echo %UserName%
  echo %Password%
  echo binary

  rem Read the CSV file line by line
  for /f "eol=: delims=" %%a in (matches3.csv) do call :parse %%a

  rem Add commands to close ftp conn
  echo close
  echo bye
)>%Commands%

rem Perform the FTP upload
echo logging in to ftp...
FTP -d -i -s:%Commands% %Server%
echo finished.
pause

rem Clean up.
if exist %Commands% del %Commands%
endlocal
exit

rem Transform CSV line into FTP put commmand
:parse
echo put "%1" "%2"
于 2012-05-30T15:57:23.270 回答
0

:end不会阻止CALL函数运行,它只是一个标签。相反,我怀疑您打算使用GOTO :eof,这将返回到 for 循环:

...
rem Read the CSV file line by line
for /f %%a in (matches3.csv) do call :parse %%a

rem Transform CSV line into FTP put commmand
:parse
echo put "%1" "%2" >> %Commands%

goto :eof

rem Add commands to close ftp conn
...

或者,您可能会发现使用括号更简单,而不是使用调用,如下所示:

...
rem Read the CSV file line by line
for /f %%a in (matches3.csv) do (
  rem Transform CSV line into FTP put command
  echo put "%%a" "%%b" >> %Commands%
)

rem Add commands to close ftp conn
...
于 2012-05-30T13:43:19.347 回答
0

也许这行得通

@echo off
setlocal EnableExtensions

rem Connection credentials
set Server=servername
set UserName=username
set Password=password

set Commands="commands.txt"
echo open %Server% > %Commands%
echo %UserName% >> %Commands%
echo %Password% >> %Commands%
echo binary >> %Commands%

rem Read the CSV file line by line
for /f %%a in (matches3.csv) do call :parse %%a

rem Transform CSV line into FTP put commmand
:parse
echo put "%1" "%2" >> %Commands%

:end
rem Add commands to close ftp conn
echo close >> %Commands%
echo bye   >> %Commands%

rem Perform the FTP upload
echo loggin in to ftp...
FTP -d -i -s:%Commands% %Server%
echo finished.
pause

rem Clean up.
if exist %Commands% del %Commands%
endlocal
exit /b



rem Transform CSV line into FTP put commmand
:parse
echo put "%1" "%2" >> %Commands%
exit /b

:end
rem Add commands to close ftp conn
echo close >> %Commands%
echo bye   >> %Commands%
exit /b
于 2013-07-08T10:07:52.693 回答