我有一个包含文件的文件夹;每个文档都应该有.pdf和.xml格式。我需要编写一个BAT文件来运行计划任务,以验证每个文档都存在。
我的逻辑是:
我知道如何使用blat发送电子邮件,但我无法执行循环。我找到了一种方法来获取没有扩展名的路径和文件名但不能合并它们。
之前我曾经使用过批处理文件,但我远非专家。我错过了什么?
这是我到目前为止的代码:
set "FolderPath=E:\TestBat\Test\"
echo %FolderPath%
for %%f in (%FolderPath%*) do (
set /p val=<%%f
For %%A in ("%%f") do (
Set Folder=%%~dpA
Set Name=%%~nxA
)
echo Folder is: %Folder%
echo Name is: %Name%
if NOT EXIST %FolderPath%%name%.xml
set flag=MISSING
if NOT EXIST %FolderPath%%name%.pdf
set flag=MISSING
)
echo %Flag%
pause
答案 0 :(得分:1)
这样的任务不需要花哨的代码:
@Echo Off
Set "FolderPath=E:\TestBat\Test"
If /I Not "%CD%"=="%FolderPath%" PushD "%FolderPath%" 2>Nul||Exit/B
Set "flag="
For %%A In (*.pdf *.xml) Do (
If /I "%%~xA"==".pdf" (If Not Exist "%%~nA.xml" Set "flag=MISSING")
If /I "%%~xA"==".xml" (If Not Exist "%%~nA.pdf" Set "flag=MISSING")
)
If Defined flag Echo=%flag%
Timeout -1
答案 1 :(得分:0)
这样的事情:
set "FolderPath=E:\TestBat\Test\"
pushd "%FolderPath%"
for %%a in (*.xml) do (
if exist "%%~na.pdf"(
echo ok
) else (
rem do what you want here
echo Missing
)
)
popd
答案 2 :(得分:0)
这是你想要的吗?
@echo off
setlocal enabledelayedexpansion
set "FolderPath=E:\TestBat\Test\"
echo !FolderPath!
for /f "usebackq delims=" %%f in (`dir !FolderPath! /B`) do (
set /p val=<%%f
For %%A in ("%%f") do (
Set Folder=%%~dpA
Set name=%%~nxA
)
echo Folder is: !Folder!
echo Name is: !name!
if NOT EXIST !FolderPath!!name!.xml set flag=MISSING
if NOT EXIST !FolderPath!!name!.pdf set flag=MISSING
)
echo Flag: !flag!
pause
endlocal
您应该重新格式化代码,并记住批处理文件的格式是至关重要的。顺便说一句,如果您尝试更新现有批处理变量并稍后阅读,则应启用localdelayedexpansion
并使用!
代替%
。
答案 3 :(得分:0)
保持简单:
@echo off
pushd "E:\TestBat\Test" || exit /B 1
for %%F in ("*.pdf") do if not exist "%%~nF.xml" echo %%~nxF
for %%F in ("*.xml") do if not exist "%%~nF.pdf" echo %%~nxF
popd
这将返回显示孤立的所有文件,即缺少具有相同名称但另一个扩展名(.pdf
,.xml
)的文件。要实现变量FLAG
以指示缺少文件,只需将& set "FLAG=missing"
附加到每个for
行,并确保FLAG
最初为空。然后,您只需使用if defined FLAG
即可查看。
注意:这不包括电子邮件通知问题。由于我不知道您提到的BLAT工具,我不知道您想如何将列出的文件传输给它(命令行参数,临时文件或 STDIN 流?)。
如果目标目录中存在大量文件,则另一种方法在性能方面可能更好,前提是文件系统访问次数大幅减少(请注意,上述脚本访问文件系统中的文件系统) for
循环体if exist
,因此每个迭代文件都是单独的)。所以这是依赖临时文件和findstr
命令的尝试:
@echo off
pushd "E:\TestBat\Test" || exit /B 1
rem // Return all orphaned `.pdf` files:
call :SUB "*.pdf" "*.xml"
rem // Return all orphaned `.xml` files:
call :SUB "*.xml" "*.pdf"
popd
exit /B
:SUB val_pattern_orphaned val_pattern_missing
set "LIST=%TEMP%\%~n0_%RANDOM%.tmp"
> "%LIST%" (
rem // Retrieve list of files with one extension:
for %%F in ("%~2") do (
rem /* Replace the extension by the other one,
rem then write the list to a temporary file;
rem this constitutes a list of expected files: */
echo(%%~nF%~x1
)
)
rem /* Search actual list of files with the other extension
rem for occurrences of the list of expected files and
rem return each item that does not match: */
dir /B /A:-D "%~1" | findstr /L /I /X /V /G:"%LIST%"
rem // Clean up the temporary file:
del "%LIST%"
exit /B
要了解它是如何工作的,让我们使用一个例子专注于第一个子例程调用call :SUB "*.pdf" "*.xml"
;让我们假设目标目录包含以下文件:
AlOnE.xml ExtrA.pdf sAmplE.pdf sAmplE.xml
因此,在for
循环中收集了.xml
个文件的列表:
AlOnE.xml sAmplE.xml
这是写入临时文件但扩展名.xml
替换为.pdf
:
AlOnE.pdf sAmplE.pdf
下一步是生成实际存在的.pdf
文件列表:
ExtrA.pdf sAmplE.pdf
将其传送到findstr
命令行,该命令行在此列表中搜索从临时文件收集的搜索字符串,仅返回不匹配的行。换句话说,findstr
仅返回输入列表中未出现在临时文件中的那些行:
ExtrA.pdf
要最终得到孤立的.xml
文件,还需要第二个子例程调用。
由于此脚本使用包含文件列表的临时文件,该文件列表由findstr
处理一次以查找每个扩展名的任何孤立文件,因此文件系统访问操作的总数较低。然而,最弱的部分是for
循环(包含字符串连接操作)。