在CMD批处理脚本中设置未设置

在CMD批处理脚本中设置未设置

我正在尝试编写一个脚本,该脚本将查找磁盘上的所有目录连接,然后在另一个位置重新创建它们。首先,我必须找到所有连接并编辑输出以使其更易读。

这是测试.txt:

 Volume in drive C has no label.
 Volume Serial Number is A0D2-DFB0

 Directory of C:\

14.07.2009.  06:08    <JUNCTION>     Documents and Settings [C:\Users]
13.01.2015.  10:26    <JUNCTION>     Users [E:\Users]
               0 File(s)              0 bytes

 Directory of C:\ProgramData

14.07.2009.  06:08    <JUNCTION>     Application Data [C:\ProgramData]
14.07.2009.  06:08    <JUNCTION>     Desktop [C:\Users\Public\Desktop]
14.07.2009.  06:08    <JUNCTION>     Documents [C:\Users\Public\Documents]
14.07.2009.  06:08    <JUNCTION>     Favorites [C:\Users\Public\Favorites]
14.07.2009.  06:08    <JUNCTION>     Start Menu [C:\ProgramData\Microsoft\Windows\Start Menu]
14.07.2009.  06:08    <JUNCTION>     Templates [C:\ProgramData\Microsoft\Windows\Templates]
               0 File(s)              0 bytes

 Directory of C:\ProgramData\Oracle\Java\javapath

24.12.2014.  18:22    <SYMLINK>      java.exe [D:\Programs\Java 8u25\bin\java.exe]
24.12.2014.  18:22    <SYMLINK>      javaw.exe [D:\Programs\Java 8u25\bin\javaw.exe]
24.12.2014.  18:22    <SYMLINK>      javaws.exe [D:\Programs\Java 8u25\bin\javaws.exe]
               3 File(s)              0 bytes

     Total Files Listed:
               3 File(s)              0 bytes
               8 Dir(s)  16.309.276.672 bytes free

- 这是我正在运行的(未完成的)脚本:

echo on

cd \

set start=
set end=
set paths=

type NUL > output.txt

for /f "tokens=* skip=3" %%l in (C:\test.txt) do (
for /f "tokens=1" %%d in ("%%l") do (
 if %%d==Directory (
    for /f "tokens=3" %%p in ("%%l") do (
      set start="%%p"
    )
 ) else (
   for /f "tokens=3" %%j in ("%%l") do (
      if %%j==^<JUNCTION^> (
          for /f "tokens=4*" %%h in ("%%l") do (
            set end="%%h"
            echo %start% %end% >> output.txt

          )
       )
    )
 )
)
)

问题是 output.txt 最终包含几行“Echo is ON”,而不是路径。如果我用任何字符串(例如“sausage”)替换“%start% %end%”,我得到的 output.txt 中就会充满香肠。如果我在脚本运行后运行 echo set %end%,输出将是“Templates”,这是预期的。我猜 set 命令在其中一个循环完成之前不会设置任何内容。

我说得对吗?有办法解决这个问题吗?我真的需要在 CMD 中运行它,因为它必须从 Windows 修复磁盘运行。

PS,我知道即使修复了这个程序,我的代码也无法达到我的目的,但我只是想先做最重要的事情。

答案1

如果您使用原始脚本并添加,setlocal enabledelayedexpansion您可以用和替换%start%%end%!start!这样!end!您的脚本就会按预期工作。

您的脚本不允许文件名中有空格,因此我建议修改以下脚本:-

echo off

setlocal enabledelayedexpansion

cd \

set start=
set end=
set paths=

type NUL > output.txt

for /f "tokens=* skip=3" %%l in (C:\test.txt) do ^
for /f "tokens=1-2*" %%d in ("%%l") do ^
if %%d==Directory (
    set start="%%f"
) else (
    for /f "tokens=3*" %%j in ("%%l") do ^
if %%j==^<JUNCTION^> (
            for /f "tokens=1 delims=[" %%n in ("%%k") do set end=%%n
            set end="!end:~0,-1!"
            echo !start! !end! >> output.txt

        )
)

我在这里做了另外两件事:-

  1. 我已经从不需要的命令中删除了括号(不幸的是,连续符后的新行^不能缩进,这会破坏第二个的格式if)。
  2. 我删除了不必要的for循环,同时允许在目录和文件名中嵌入空格。

我把它们留在里面,但初始cd \set初始化是不必要的,尽管你可能希望在退出之前清除start它们end

答案2

替换并echo %start% %end% >> output.txt附加call :forecho最后一个脚本行下方的下一个代码片段:

goto :eof

:forecho
    echo %start% %end% >> output.txt
goto :eof

问题实际上在于 %variables% 是在解析时逐条命令展开的,而不是在执行时展开的。并且所有括在(括号中的代码片段)都被视为唯一命令。

为了安全起见,脚本的开头应该是

@ECHO OFF >NUL
@SETLOCAL enableextensions disabledelayedexpansion

整个脚本可能如下所示:

@ECHO OFF >NUL
@SETLOCAL enableextensions disabledelayedexpansion
cd \
set start=
set end=
set paths=
type NUL > output.txt

for /f "tokens=* skip=3" %%l in (C:\test.txt) do (
for /f "tokens=1" %%d in ("%%l") do (
 if %%d==Directory (
    for /f "tokens=3" %%p in ("%%l") do (
      set start="%%p"
    )
 ) else (
   for /f "tokens=3" %%j in ("%%l") do (
      if %%j==^<JUNCTION^> (
          for /f "tokens=4*" %%h in ("%%l") do (
            set end="%%h"
            call :forecho
          )
       )
    )
 )
)
)
@ENDLOCAL
goto :eof

:forecho
    echo %start% %end% >> output.txt
goto :eof

相关内容