【问题标题】:How to redirect output of a command to a file of which name is defined in an environment variable?如何将命令的输出重定向到环境变量中定义名称的文件?
【发布时间】:2017-11-03 11:39:13
【问题描述】:

我想将文件夹下所有文件的绝对路径存储到一个文本文件中,比如说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

【问题讨论】:

  • 你的报价不对,把set origDir= %cd%改成set "origDir=%cd%"(注意等号后面的空格)和set temporaryFile="!origDir!\temp.txt"改成set "temporaryFile=!origDir!\temp.txt"

标签: windows batch-file


【解决方案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: 的根目录。阅读 this answer 了解有关命令 SETLOCALENDLOCAL 的详细信息。

也可以,但不推荐:

@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保存文件名,完整路径已经用双引号括起来,因此DIR命令行在Windows命令解释器预处理后执行为:

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 /?

另请阅读有关 Using Command Redirection Operators 的 Microsoft 文章。

【讨论】:

    【解决方案2】:

    %0 是一个特殊变量,指的是运行脚本。如果您想引用保存该脚本的位置,您可以随时使用它的驱动器和路径的扩展形式%~dp0,以反斜杠结尾,D:\my work\

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

    Dir/B/S/A-D C:\>"%~dp0temp.txt"
    

    注意,我已将您的输出文件名用双引号括起来以保护包含的空间。因为您正在对系统驱动器运行Dir 命令,所以也可以选择建议从输出中排除连接和系统文件Dir/B/S/A-D-L-S

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      • 2011-04-10
      • 2012-03-01
      • 2021-10-04
      • 1970-01-01
      • 2012-05-06
      • 2012-07-05
      相关资源
      最近更新 更多