如何将命令的输出重定向到在环境变量中定义了名称的文件?

时间:2017-11-03 11:39:13

标签: windows batch-file

我想将文件夹下存在的所有文件的绝对路径存储到文本文件中,让我们说temp.txt

我正在使用此命令执行此任务:

dir /s/b/a-d > D:\my work\temp.txt

当我重定向到硬编码到批处理文件中的文件名时,上面的命令工作正常。

但是当我使用如下面代码所示的变量时,我没有将输出重定向到文件temp.txt

@echo off
setlocal enabledelayedexpansion
REM I am running this script from D:\my work\
set origDir= %cd%
cd C:\
set temporaryFile="!origDir!\temp.txt"
dir /s/b/a-d > !temporaryFile!

为什么 DIR 的输出未写入D:\my work\temp.txt

2 个答案:

答案 0 :(得分:1)

Why is no string output with 'echo %var%' after using 'set var = text' on command line?上的答案命令行出了什么问题:

set origDir= %cd%

命令 SET 不会忽略等号后面的空格。因此,环境变量origDir的字符串值使用前导空格字符定义。

接下来的命令行

set temporaryFile="!origDir!\temp.txt"

会在字符串" D:\my work\temp.txt"中生成大小写,并将双引号分配给环境变量temporaryFile

因此,带有用双引号括起的路径的文件名无效,因为以空格字符开头。

您的任务的可能代码是:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "origDir=%CD%"

rem Current directory path usually does not end with a backslash. But on
rem current directory being root of a drive it ends with a backslash which
rem should be removed to correct concatenate it with backslash and file name.

if "%origDir:~-1%" == "\" set "origDir=%origDir:~0,-1%"
set "temporaryFile=%origDir%\temp.txt"
cd /D C:\
dir /A-D /B /S >"%temporaryFile%"
endlocal

此处不需要使用延迟环境变量扩展。

命令 CD 仅当使用参数/D并且指定的目录不在被引用的网络共享上时,才将当前目录更改为与当前驱动器不同的驱动器上的指定目录与UNC路径。

启用命令扩展的 PUSHD 命令也适用于UNC路径, POPD 可以恢复初始当前目录。

嗯,命令 ENDLOCAL 还在上面的批处理文件中恢复了当前的初始目录。从D:\my work为当前目录的命令提示符窗口中运行此批处理文件时可以看到这一点。虽然批处理文件更改为驱动器echo %CD%的根目录,但在运行批处理文件后执行D:\my work会输出C:。有关命令 SETLOCAL ENDLOCAL 的详细信息,请阅读this answer

也可以但不推荐:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "origDir=%CD%"
if "%origDir:~-1%" == "\" set "origDir=%origDir:~0,-1%"
set "temporaryFile="%origDir%\temp.txt""
cd /D C:\
dir /A-D /B /S >%temporaryFile%
endlocal

环境变量temporaryFile保存文件名,其中完整路径已用双引号括起来,因此在Windows命令解释程序预处理之后执行 DIR 命令行:

dir /A-D /B /S  1>"D:\my work\temp.txt"

通常,不建议将已用双引号括起来的文件夹或文件名分配给环境变量,因为如果稍后在批处理代码中将变量值与其他字符串连接起来,这很容易导致意外行为,例如,请参阅How to set environment variables with spaces?

但此任务的最短版本是单个命令行:

@dir C:\* /A-D /B /S >temp.txt

单个命令行与上面所有这些命令的两个批处理文件完全相同。它在当前目录D:\my work中创建一个文件temp.txt,其中包含整个驱动器C:上所有文件的名称,其中包含当前用户帐户具有列出目录条目权限的完整路径。

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • cd /?
  • dir /?
  • echo /?
  • endlocal /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?

另请阅读Microsoft有关Using Command Redirection Operators

的文章

答案 1 :(得分:1)

%0是一个特殊变量,它指的是正在运行的脚本。如果您想要引用包含该脚本的位置,您可以随时使用它的驱动器和路径%~dp0的扩展表单,该结构以反斜杠结尾{{1} }

考虑到这一点,无论您当前的目录如何,您都应该能够安全地在脚本中使用此行:

D:\my work\

注意,我已将输出文件名用双引号括起来以保护包含的空格。因为您正在对系统驱动器运行Dir/B/S/A-D C:\>"%~dp0temp.txt" 命令,所以还可以选择从输出中排除联结和系统文件Dir