抑制FORFILES“找不到文件”错误

时间:2013-05-29 17:50:32

标签: batch-file

我正在使用批处理文件删除超过14天的存档文件,我正在调用自动​​化过程(Lansa Composer)中的文件,该文件读取脚本的返回代码以查看是否存在问题。这是脚本:

@echo off
@Echo Deleting files older than 14 days...
cd /d C:\Windows\System32
FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c del @file"

问题是该脚本返回错误代码并打印“错误:找不到具有指定搜索条件的文件”如果找不到要删除的文件,当我真的只希望它返回错误时是访问目录或运行del命令等问题。是否有某种方法可以让这个脚本抑制“找不到文件”错误,但允许其他人通过?

经过一些谷歌搜索我尝试了this page上的解决方案,但它们不能满足我的需要,因为在第一种情况下它会抑制所有错误,在第二种情况下会传递错误消息的文本,但实际的返回代码仍然被抑制(这是自动化过程读取的内容)。

8 个答案:

答案 0 :(得分:11)

这应解决这个问题:

@echo off
Echo Deleting files older than 14 days...
cd /d C:\Windows\System32
copy /b forfiles.exe "[file path...]\IDOC_ARCHIVE" >nul
FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c del @file"

它的作用是提供超过14天的文件 - 因此它将始终被删除,并且不会显示“找不到文件”消息。我选择了forfiles.exe进行复制,但您可以使用超过14天的任何文件。所有其他错误消息将正常显示。

答案 1 :(得分:5)

解决方案是在FOR循环中捕获FORFILES命令的输出,搜索以ERROR开头的字符串,并将结果存储在变量中。从那里,您可以使用IF / ELSE指令相应地设置errorlevel。这是代码(减去一些记录和注释):

cd /d C:\Windows\System32
SET _CmdResult=NONE
FOR /F "tokens=*" %%a IN ('FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c DEL @file" 2^>^&1 ^| FINDSTR ERROR') DO SET _CmdResult=%%a
IF "%_CmdResult%" == "ERROR: No files found with the specified search criteria." ( 
    SET errorlevel=0 
 ) ELSE ( 
    SET errorlevel=1
 )
IF "%_CmdResult%" == "NONE" SET errorlevel=0

请确保在FOR循环中转义任何字符,例如>&|

答案 2 :(得分:4)

添加2> nul就可以了。谢谢!

forfiles / p d:\ todayfiles / d +0 / c“cmd / c echo @path” 2> nul |找到“:”/ c

答案 3 :(得分:3)

我可能会为这个已经很有价值的帖子添加一份不起眼的贡献。我发现其他解决方案可能会删除实际的错误文本,但忽略了%ERRORLEVEL%,这表示我的应用程序出现故障。只要它不是“找不到文件”错误,我合法地想要%ERRORLEVEL%。

一些例子:

专门调试并消除错误:

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||echo found success

使用oneliner返回ERRORLEVEL成功或失败:

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT /B 1||EXIT /B 0

使用oneliner将ERRORLEVEL保持为零,以便在其他代码中的批处理文件的上下文中成功(ver> nul重置ERRORLEVEL):

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||ver > nul

对于SQL Server代理CmdExec作业步骤,我登陆了以下内容。我不知道这是不是一个错误,但步骤中的CmdExec只识别第一行代码:

cmd /e:on /c "forfiles /p "C:\SQLADMIN\MAINTREPORTS\SQL2" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT 1||EXIT 0"&exit %errorlevel%

答案 4 :(得分:2)

为了可靠地影响ERRORLEVEL,您需要运行后续命令,该命令保证将ERRORLEVEL设置为0。 我使用命令解释器本身(cmd.exe)执行此操作,如以下代码段所示:

FORFILES  /M:somefiles /D -14 2>nul | cmd /c ""

希望这有助于某人。

答案 5 :(得分:2)

使用一个衬垫很容易解决这个问题。只需将其附加到您的forfiles命令:

2>&1 | find /v /i "ERROR: No files found with the specified search criteria."

所以你得到:

FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c del @file" 2>&1 | find /v /i "ERROR: No files found with the specified search criteria."

仅显示指定的错误消息。所有其他消息都是。

以下是如何运作的:

  • 2>&1用于将STDERR发送到我们发送STDOUT的same place
  • | find /v /i pipesforfilesfind的输出,其中/v表示不包含指定的字符串,/i表示不区分大小写< / LI>

答案 6 :(得分:0)

当尝试删除ext硬盘上的年度备份中的重复项时,我遇到了相同的问题。 没有找到在Internet上搜索的解决方案(在命令参数中添加select coalesce(pin.year, pout.year) as year, coalesce(pin.month, pout.month) as month, coalesce(pin.cnt, 0) as count_in, coalesce(pout.cnt, 0) as count_out from ( select year(date_created) as year, month(date_created) as month, count(*) as cnt from person group by year(date_created), month(date_created) ) pin full outer join ( select year(date_left) as year, month(date_left) as month, count(*) as cnt from person group by month(date_left), year(date_left) ) pout on pout.year = pin.year and pout.month = pin.month order by year, month; ,而在命令参数中省略@path)对我没有用。系统询问“您确定...”后,我想到了以下解决方案:使用cmd /c参数。 结果在我的2016目录中擦除了2015文件:

/q

答案 7 :(得分:0)

尝试在脚本之后添加

2>Nul 

示例

SET Days=14

FORFILES /S /M *.* /D -%Days% /C "CMD /C DEL @file" 2>Nul

希望有帮助。