WinSCP批处理实现仅追加远程文件非重复内容至本地文件
实现SFTP远程文件非重复内容追加到本地的方案
WinSCP本身的get -append命令只会直接追加内容,不会自动去重。要实现仅追加本地文件中不存在的非重复行,我们可以结合WinSCP的文件下载能力,再用本地脚本(PowerShell或CMD工具)完成去重对比。下面是具体的可行方案:
方案思路
- 先将远程文件下载到本地临时文件(避免直接修改目标文件)
- 对比临时文件和本地目标文件,筛选出本地没有的行
- 将筛选出的新行追加到本地目标文件
- 可选:根据需求处理远程文件(比如删除或保留)
- 清理临时文件
具体脚本实现
下面是修改后的批处理脚本,结合PowerShell完成精准去重逻辑:
@echo off setlocal enabledelayedexpansion :: 配置参数,请根据实际情况替换 set "WINSCP_PATH=C:\Program Files (x86)\WinSCP\WinSCP.com" set "LOG_PATH=C:\Users\U37615\Documents\POCLOSEBATCHLOG\WinSCP.log" set "REMOTE_FILE=xxxxxx" :: 你的远程文件路径 set "LOCAL_FILE=xxxxxxx" :: 你的本地目标文件路径 set "TEMP_FILE=%TEMP%\remote_temp.txt" :: 1. 下载远程文件到临时文件 "%WINSCP_PATH%" ^ /log="%LOG_PATH%" /ini=nul ^ /command ^ "open xxxxxx -hostkey=""ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx....""" ^ "get ""%REMOTE_FILE%"" ""%TEMP_FILE%""" ^ "exit" set WINSCP_RESULT=%ERRORLEVEL% if %WINSCP_RESULT% neq 0 ( echo 下载远程文件失败,请检查日志 pause exit /b %WINSCP_RESULT% ) :: 2. 对比并追加非重复内容 if not exist "%LOCAL_FILE%" ( :: 本地文件不存在时直接复制临时文件内容 copy "%TEMP_FILE%" "%LOCAL_FILE%" ) else ( :: 用PowerShell筛选出本地没有的行,追加到目标文件 powershell -Command "$localLines = Get-Content '%LOCAL_FILE%' -ErrorAction SilentlyContinue; Get-Content '%TEMP_FILE%' | Where-Object { $_ -notin $localLines } | Add-Content '%LOCAL_FILE%'" ) :: 3. 可选:删除远程文件(如果需要同步后清除远程内容,取消下面注释) :: "%WINSCP_PATH%" ^ :: /log="%LOG_PATH%" /ini=nul ^ :: /command ^ :: "open xxxxxx -hostkey=""ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx....""" ^ :: "rm ""%REMOTE_FILE%""" ^ :: "exit" :: 4. 清理临时文件 del "%TEMP_FILE%" echo 非重复内容追加完成 pause exit /b 0
关键细节说明
- 临时文件:使用系统临时目录的文件,避免占用目标文件所在目录空间,处理完成后自动清理
- PowerShell去重逻辑:
Where-Object { $_ -notin $localLines }精准过滤掉本地已存在的行,只追加全新内容 - 兼容空文件:如果本地目标文件不存在,直接复制临时文件内容,避免报错
- 错误处理:保留WinSCP的错误码检查,确保下载失败时能及时提示
替代方案(纯CMD工具)
如果你的环境无法使用PowerShell,可以用findstr实现基础去重(注意:findstr对长行、特殊字符支持有限,且区分大小写):
:: 替换脚本中PowerShell部分为以下代码 if not exist "%LOCAL_FILE%" ( copy "%TEMP_FILE%" "%LOCAL_FILE%" ) else ( :: 找出临时文件中不在本地文件的行 findstr /v /g:"%LOCAL_FILE%" "%TEMP_FILE%" > "%TEMP%\new_lines.txt" :: 如果有新行则追加到本地文件 if exist "%TEMP%\new_lines.txt" ( type "%TEMP%\new_lines.txt" >> "%LOCAL_FILE%" del "%TEMP%\new_lines.txt" ) )
内容的提问来源于stack exchange,提问作者Joshua Averbuch




