【问题标题】:CMD: FINDSTR: Cannot open FilenameCMD:FINDSTR:无法打开文件名
【发布时间】:2021-08-27 11:22:19
【问题描述】:

我遇到了这个非常奇怪且无法解释的问题,让我困惑了很长一段时间。每次我遇到这个问题时,我都无法弄清楚出了什么问题,因为它与其他变量相同。

我知道可能有一些论坛页面夹在与此相关的数千个页面之间,我可以在其中找到我的答案,但是我找不到千分之一的页面。

所以我正在编写一个脚本来运行过滤器,它工作正常,除了这个给我错误消息的愚蠢和顽固的变量。

因此,当我从名为 Test.bat 的 Bat-File 运行以下命令时(为了保持名称简短),它会在之后给我错误消息。

代码:

@ECHO off
    set CNAME="RefilterMe"
    SET SPT="C:\ICT\RefilterMe.txt"
    SET SPT2="C:\ICT\%CNAME%.ReFiltered.txt"
    SET SPT3="C:\ICT\%CNAME%.Temp.txt"
    SET SPT4="C:\ICT\Refiltered"
    SET SPT5="C:\ICT\%CNAME%.Programms.txt"
    SET SPT6="C:\ICT\%CNAME%.Temp2Test.txt"
    SET SPT7="C:\ICT\%CNAME%.Filtered.Temp.txt"

TYPE %SPT% > %SPT5%

错误:

FINDSTR: Cannot open C:\ICT"RefilterMe.Programms.txt"

在写我的问题时,我当然意识到它说的是 'C:\ICT"RefilterMe.Proper.txt"' 而不是 'C:\ICT\RefilterMe.Programms.txt'。 'TYPE %SPT% > %SPT5%' 的部分直接放在可变区域/区域的后面,很奇怪,它只发生在这一行。

这里有一些分析信息。

测试:

复制 SPT6 并将其命名为 SPT8。这个没有问题。但是,当我将其更改为 SPT5 并将 SPT5 更改为 SPT8 时,问题也随之发生了变化。

@ECHO off
    set CNAME="RefilterMe"
    SET SPT="C:\ICT\RefilterMe.txt"
    SET SPT2="C:\ICT\%CNAME%.ReFiltered.txt"
    SET SPT3="C:\ICT\%CNAME%.Temp.txt"
    SET SPT4="C:\ICT\Refiltered"
    SET SPT8="C:\ICT\%CNAME%.Programs.txt"
    SET SPT6="C:\ICT\%CNAME%.Temp2Test.txt"
    SET SPT5="C:\ICT\%CNAME%.Programms.txt"
    SET SPT7="C:\ICT\%CNAME%.Filtered.Temp.txt"

TYPE %SPT% > %SPT5%
TYPE %SPT% > %SPT8%

我测试的越多,它就越复杂。完全删除 SPT5 只会给出“无法打开”,而不会添加无法打开的内容。太奇怪了,我不知为何不知所措。如果我将 SPT5 从 %CNAME% 更改为 RefilterMe,它会正常工作,但我很想知道为什么会出现这个奇怪的问题,也许这个论坛上的某个人有一个想法。

编辑:根据 Compo 的要求。

更大的代码部分可以更好地帮助您理解问题。

@ECHO off
    set CNAME="RefilterMe"
    SET SPT="C:\ICT\RefilterMe.txt"
    SET SPT2="C:\ICT\%CNAME%.ReFiltered.txt"
    SET SPT3="C:\ICT\%CNAME%.Temp.txt"
    SET SPT4="C:\ICT\Refiltered"
    SET "SPT5=C:\ICT\%CNAME%.Programms.txt"
    SET SPT6="C:\ICT\%CNAME%.Temp2Test.txt"
    SET SPT7="C:\ICT\%CNAME%.Filtered.Temp.txt"

TYPE %SPT% > %SPT5%
ECHO . > %SPT2%

ECHO Cleaning Collected Entries ...

ECHO Programms > %SPT7%


::First part with possible common programms

    (FindStr /IC:"Microsoft Edge" "%SPT5%" >Nul && (ECHO Edge))>> %SPT7%
    (FindStr /IC:"Mozilla Firefox" "%SPT5%" >Nul && (ECHO Firefox))>> %SPT7%

为了增加一点混乱,我编写的原始脚本中的变量设置将包含过滤部分。这样就没有非常奇怪的错误。

WMIC bios get serialnumber > C:\SN.txt
::Extracting only the serialnumber from the txt file
TYPE C:\SN.txt | findstr /v /c:"SerialNumber" > C:\SN1.txt
FOR /f "delims=" %%x in (C:\SN1.txt) DO SET SN1=%%x
::Defining the variable for the Filename
SET "SN=%SN1: =%"
::Deleting the created Files
DEL C:\SN.txt
DEL C:\SN1.txt

::Defining Save Paths (SPT) and the Move Path (MPT) of the Tool
SET MPT="\\<IP Address>\<Path>\ICT"
SET SPT="C:\%COMPUTERNAME%.%SN%.Complete.txt"
SET SPT2="C:\%COMPUTERNAME%.%SN%.Filtered.txt"
SET SPT3="C:\%COMPUTERNAME%.%SN%.Temp.txt"
SET SPT4="C:\%COMPUTERNAME%.%SN%.Screen.txt"
SET SPT5="C:\%COMPUTERNAME%.%SN%.Programs.txt"
SET SPT6="C:\%COMPUTERNAME%.%SN%.Screen.Temp.txt"
SET SPT7="C:\%COMPUTERNAME%.%SN%.Filtered.Temp.txt"

希望这能让事情更清楚。

【问题讨论】:

  • 我的猜测:路径扩展。当 cmd CLI 解析 %SPT5% 路径时,它会看到可能与当前路径或 %PATH% 中的目录匹配的“程序”。因此,它将其转换为"Programms[space]...",这确实使原来的双引号变浅了。如果你像这样引用你的变量会发生什么:SET "CNAME=..." SET "SPT=..."
  • 您不应使用set 命令引用该值。使用首选语法set "var=value"(注意引号的位置)。这可以防止毒字符,但不包括引号。稍后,在使用变量时,在适当的地方使用引号:SET "SPT5=C:\ICT\%CNAME%.Programms.txt"(值中仍然没有引号)和后来的findstr "stringtofind" "%spt2%"
  • 我曾尝试将 Programms 重命名为正确的,但仍然如此。很抱歉漏掉了这个。
  • 除非我半睡半醒,否则当您的示例中没有使用该实用程序的单个命令或行时,我正在努力确定您如何从 findstr.exe 收到错误消息.这个网站的想法是您提交足够的信息让我们重现您的问题,老实说,看到来自您未使用的实用程序/命令的错误消息让我大吃一惊。请说明使用该实用程序的位置,edit 您的问题包括minimal reproducible example。从您提交的两个示例中,唯一使用正确语法的命令是第一行 @ECHO off
  • 由于它不适合评论,我将添加一个简单的示例来解释发生的事情。

标签: batch-file variables cmd


【解决方案1】:

这里是您的用例中的一个简单批处理,说明了为什么 FINDSTR 无法在您的实际脚本中找到包含 %CNAME 的文件:

@ECHO off
    set CNAME="RefilterMe"
    SET SPT="C:\ICT\RefilterMe.txt"
    SET SPT2="C:\ICT\%CNAME%.ReFiltered.txt"
    SET SPT3="C:\ICT\%CNAME%.Temp.txt"
    SET SPT4="C:\ICT\Refiltered"
    SET SPT8="C:\ICT\%CNAME%.Programs.txt"
    SET SPT6="C:\ICT\%CNAME%.Temp2Test.txt"
    SET SPT5="C:\ICT\%CNAME%.Programms.txt"
    SET SPT7="C:\ICT\%CNAME%.Filtered.Temp.txt"

call echo "more < %SPT4%"
more < %SPT4%

call echo "more < %SPT3%"
more < %SPT3%

call echo "more < %SPT5%"
more < %SPT5%

call echo "more < %SPT8%"
more < %SPT8%

for %%i in (%SPT3%) do echo %%i
for %%i in (%SPT4%) do echo %%i
for %%i in (%SPT5%) do echo %%i
for %%i in (%SPT8%) do echo %%i

call echo "FINDSTR x %SPT3%"
FINDSTR x %SPT3%
call echo "FINDSTR x %SPT4%"
FINDSTR x %SPT4%
call echo "FINDSTR x %SPT5%"
FINDSTR x %SPT5%
call echo "FINDSTR x %SPT8%"
FINDSTR x %SPT8%

它的输出带有 'aax''bxb'、'xee'_、'xff' 作为内容的文件:

"更多

正如您所看到的%SPT3%,FINDSTR 命令将为FINDSTR x "C:\ICT\"RefilterMe".Temp.txt"。由于它不是重定向中的路径 (&lt; "path"),因此它们不会删除引号。然后FINDSTR 将尝试按原样查找文件"C:\ICT\"RefilterMe".Temp.txt",然后修剪引号,但是由于存在转义引号(C:\ICT\" 中的\"),因此该引号保持原样。因此,FINDSTR 将寻找C:\ICT"RefilterMe.Temp.txt。而且确实找不到。

如果您将set CNAME="RefilterMe" 更改为set "CNAME=RefilterMe",您将看到脚本的行为与FINDSTR 命令的预期一样。

cmd batch 变量值不是值的重要部分时,我建议您尽可能避免使用引号。你应该用这种方式修复你所有的SET

【讨论】:

  • 似乎已经做到了。非常感谢。也是为了解释。我没有完全理解,但你是对的。从现在开始,我应该像这样设置我的变量:>set "CNAME=RefilterMe"
  • 发现一个“x=something”不起作用的情况。在主脚本中我有这个。 SET "MPT=\\\Example (Example)\ICT" MOVE %SPT% %MPT% MOVE %SPT2% %MPT% MOVE %SPT4% %MPT% 错误:命令的语法不正确。当我以另一种方式使用 Set var="something" 时,它会按预期工作。我试过了,这是由于路径中的空间。但遗憾的是,这个空间不得不留下来。 :/ 有什么建议吗?
  • 保留SET "MPT=\\IP\Example (Example)" 并用MOVE 对变量的使用 进行双引号:MOVE "%SPT%" "%MPT%" 等。在这里,引号对MOVE 命令有意义,它将完全采用未引用的值,包括空格。
猜你喜欢
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 2019-08-28
相关资源
最近更新 更多