【问题标题】:what is the difference between echo %%~fF and echo %%~fF >> file.txt within recursive calls递归调用中的 echo %%~fF 和 echo %%~fF >> file.txt 有什么区别
【发布时间】:2021-01-31 07:53:11
【问题描述】:

我想列出具有给定嵌套级别的子目录。控制台显示工作正常,但是在将相同的回显附加到文件时,它的行为会有所不同。

@echo off
setlocal

set currentLevel=0
set maxLevel=%1
if not defined maxLevel set maxLevel=1
 
:procFolder
pushd %1 2>nul
if %currentLevel% lss %maxLevel% (
  for /d %%F in (*) do (
    echo %%~fF
    echo %%~fF >> list.txt
    set /a currentLevel+=1
    call :procFolder "%%F"
    set /a currentLevel-=1
  )
)
popd

使用参数 3 调用批处理文件会写入预期嵌套三个子文件夹的 shell

D:\erroronline1\code\learntoshell\sub1
D:\erroronline1\code\learntoshell\sub1\sub2
D:\erroronline1\code\learntoshell\sub1\sub2\sub3

但在实际文件中只写了第一级递归

D:\erroronline1\code\learntoshell\sub1

这发生在所有可能的子文件夹中,只是附加了第一级嵌套。 我无法使用其他列出子目录的方法来控制嵌套级别(对于 /r %%F in (.), dir /s),因此这不会作为一个选项出现。 暂停递归(等待文件被写入,无论如何)或将文件夹传递给变量也没有帮助。

我错过了什么?递归调用中的 echo 和 echo >> 文件有什么区别?

【问题讨论】:

  • 你知道什么是参数,以及如何使用它们分配的变量吗?我非常怀疑这里分配的预期编号set maxLevel=%1 也将是目录名称pushd %1。另外,您是否真的试图从同一部分中调用批处理文件的部分?
  • 你试过call :procFolder "%%~fF"吗?
  • @Compo 当我回显变量 maxLevel 和 currentLevel 时一切看起来都不错,所以我假设 pushd %1 从调用命令中检索其参数,并将 %%F 作为第一个参数传递。
  • @aschipfl 是的,我试过没有效果
  • 是的,当然是,但这不是我要表达的意思。我的意思很简单,你的前两个 %1 实例都是出于两个完全不同的目的

标签: file batch-file append echo


【解决方案1】:

pushd 改变当前目录。 重定向的回显输出附加到当前目录中的文件中。

将日志文件从当前目录更改为完整路径,您将在一个文件中获取所有日志记录,而不是嵌套目录中的多个文件。

【讨论】:

  • if not defined maxLevel set maxLevel=1 之后到Call :procFolder . 1> "list.txt" 之后可能更有意义,然后是GoTo :EOF。然后只需将echo %%~fF >> list.txt 更改为Echo %%~fF 1> CON
  • @OJBakker omfg 这很有意义!我对工作中的所有文件夹做了什么?!
【解决方案2】:

您可以使用 实用程序将事情简化为两行

示例:通过传递两个参数来运行它,第一个是您的目录,第二个是您的级别数,例如test.cmd "%UserProfile%\Downloads" 3

@Set /A Levels = %~2 + 1
@"%__APPDIR__%Robocopy.exe" "%~1" "%~1" /E /L /LEV:%LEVELS% /NC /NS /NFL /NJH /NJS 1> "list.txt"

而且,如果你真的不想要前导空格:

@Set /A Levels = %~2 + 1
@(For /F Tokens^=* %%G In ('%__APPDIR__%Robocopy.exe "%~1" "%~1" /E /L /LEV:%LEVELS% /NC /NS /NFL /NJH /NJS 2^> NUL') Do @Echo %%G) 1> "list.txt"

[编辑/]

根据您的评论,这里只修改了一个参数,即test.cmd 3(使用当前目录作为基础)

@Set /A Levels = %~1 + 1
@"%__APPDIR__%Robocopy.exe" . . /E /L /LEV:%LEVELS% /NC /NS /NFL /NJH /NJS 1> "list.txt"

并且,再次没有前导空格:

@Set /A Levels = %~1 + 1
@(For /F Tokens^=* %%G In ('%__APPDIR__%Robocopy.exe . . /E /L /LEV:%LEVELS% /NC /NS /NFL /NJH /NJS 2^> NUL') Do @Echo %%G) 1> "list.txt"

请确保,如果这是重要的,首先检查有效的输入参数。

【讨论】:

  • 这太棒了!没有回答我在递归调用期间出现奇怪行为的问题,但可以完美地完成这项工作,而且速度要快得多!我将参数处理和 robocopy 源重新调整为“。”直接从包含目录使用脚本,但这只是味道。非常感谢!
  • edit 再次非常优雅。顺便说一句,我发现 /xd .* 省略了像 .git 这样的隐藏文件夹,如果这对任何遇到这个问题的人来说都很重要。
猜你喜欢
  • 1970-01-01
  • 2015-07-22
  • 2020-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-12
  • 2013-08-09
  • 2022-12-13
相关资源
最近更新 更多