循环浏览文件夹中的文件并检查它们是否具有不同的扩展名

时间:2016-11-30 10:05:47

标签: windows batch-file

我有一个包含文件的文件夹;每个文档都应该有.pdf和.xml格式。我需要编写一个BAT文件来运行计划任务,以验证每个文档都存在。

我的逻辑是:

  1. 循环浏览文件夹
  2. 中的文件
  3. 将每个文件剥离为其名称,不带扩展名
  4. 检查.xml和pdf是否存在相同的名称文件。
  5. 如果没有将标志变量标记为问题
  6. 完成后,如果标记了标志变量,则发送电子邮件通知
  7. 我知道如何使用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
    

4 个答案:

答案 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循环(包含字符串连接操作)。