如何在启用延迟扩展的DOS批处理中列出文件名包含感叹号的文件?

3

我有两个txt文件,分别为“test-exclamations!!!.txt”和“test-normal.txt”,以及一个批处理文件,在同一文件夹中包含以下脚本。

ECHO OFF & CLS
SETLOCAL ENABLEDELAYEDEXPANSION

FOR /F "tokens=* delims=" %%a IN ('dir /b *.txt') DO (
    set /a count=count+1
    echo !count!:%%a
)

ENDLOCAL
EXIT/B

我得到的结果如下:

1:test-exclamations.txt
2:test-normal.txt

我们可以看到感叹号已经消失了。
我有一些方法可以从互联网上获取感叹号标记,但是我无法同时保留感叹号标记和变量"count"的值。

请告诉我如何同时保留它们。

3个回答

4
@ECHO OFF
    setlocal enableextensions disabledelayedexpansion

    FOR /F "tokens=* delims=" %%a IN ('dir /b *.txt') DO (
        set /a "count+=1"
        set "file=%%a"
        setlocal enabledelayedexpansion
        echo !count!:!file!
        endlocal
    )

    endlocal

1
dir /b test-*.txt|findstr /n "^"

在延迟扩展模式下,将实现您指定的结果。

1
另一种选择是在FOR /F循环处理列表之前转义可能存在的任何!^。使用纯批处理会很困难和慢,但如果使用名为REPL.BAT的混合JScript/batch实用程序执行stdin上的正则表达式搜索和替换,并将结果写入stdout,则非常简单和快速。该实用程序是纯脚本,可在任何Windows机器上从XP开始运行。假设REPL.BAT在您的当前目录中,或者更好的是,在您的路径中的某个位置:
@echo off
setlocal enabledelayedexpansion

for /f "eol=: delims=" %%a in ('dir /b *.txt^|repl "\^^|^!" "^^$&"') do (
  set "file=%%a"!
  set /a count+=1
  echo !count!:!file!
)

文件名可能包含!和/或^。如果命令行中还包含!,则必须对^进行转义。我不确定是否存在!,因此我会盲目转义^!,然后在SET语句中附加一个额外的!。尾随的!可以正确触发^转义处理,但它出现在最后一个"之后,因此被SET命令忽略。
请注意,原始帖子中的"tokens=* delims="是冗余的。文件名可能以;开头,在这种情况下,隐式的EOL=;会导致该文件被跳过。但是文件名不能以:开头,所以我使用了"eol=: delims="
我的代码完全正常。但考虑到原问题,我会选择使用Magoo解决方案。MC ND解决方案也不错。它们比我的解决方案更简单。
然而,问题很容易扩展,使得Magoo或MC ND的解决方案都无法使用。假设在需要延迟扩展的循环内必须进行其他变量操作,并且这些操作的结果必须被保留。例如,您可能想要在单个变量中构建一个逗号分隔的值列表。这不是一个很好的例子,因为列表可能超过8191字节的最大变量长度。但它可以说明问题。
有专门的代码来在ENDLOCAL障碍中传输变量值。但这段代码很棘手,也会明显减慢循环速度。
REPL.BAT方法非常简单、快速和方便。
@echo off
setlocal enableDelayedExpansion
set "list="
set "cnt=0"
for /f "delims=" %%A in ('dir /b *.txt^|repl "\^^|^!" "^^$&"') do (
  set /a cnt+=1
  set "list=!list!, !cnt!:"%%A""
)
set "list=!list:~2!"
echo list=!list!

谢谢你们的帮助,但我需要纯批处理方式,^_^ - mts
@mts - 因为这是一个规定纯批处理的任务吗?除非您的计算机上某种方式禁用了标准JSCRIPT(或CSCRIPT引擎),否则混合方法将在任何从XP开始的Windows计算机上都可以使用。 - dbenham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接