【问题标题】:Get all files from dir and all subdirs EXCEPT one subdir从目录和所有子目录中获取所有文件,除了一个子目录
【发布时间】:2016-11-15 14:16:53
【问题描述】:

我目前在 Windows 批处理文件中使用这一行:

@ REM List all *.f in current dir and all its subdirs
dir *.f /B /S > temp1.txt

不幸的是,其中一个子目录(我们将其命名为pest)有一个非常大的子树,这使得该过程非常缓慢。由于pest 子目录对于这个特定任务实际上并不重要(它不应该包含任何相关文件),我想从搜索中排除它。

因此,我不想在当前目录和所有子目录中搜索,而是在当前目录和除pest 之外的所有子目录中搜索。

你能提出一个简单的方法吗?

【问题讨论】:

  • DIR 命令的结果通过管道传送到FIND 命令,并在FIND 命令中使用/V 选项。
  • @Squashman,这并不妨碍dir /S 枚举目录,据我所知,这是问题的意图......

标签: batch-file cmd windows-console


【解决方案1】:

您可以使用 RoboCopy 中的目录排除功能:

@Echo Off

(Set SrcDir=C:\Users\Parker\Documents)
(Set SrcMsk=*.f)
(Set ToExcl=pest)
(Set OutPut=temp1.txt)

>"%OutPut%" (For /F "Tokens=*" %%A In ('RoboCopy "%SrcDir%" NULL %SrcMsk%^
 /L /S /FP /NDL /NS /NC /NJH /NJS /XD "%ToExcl%"') Do Echo=%%A)

根据需要在括号内的四行中进行相关更改。

【讨论】:

  • 由于某种原因,这不仅返回 *.f 文件,还返回所有文件?
  • 抱歉,我的回答中有一个错字,(它说的是 %ScrMsk% 而不是 %SrcMsk%),现已修复。
【解决方案2】:

如果pest 是根目录的直接子目录(即当前目录.),您可以执行以下操作:

rem // Enumerate immediate child files in the root, output them:
> "temp1.txt" (for %%F in (".\*.f") do @echo %%~fF)
rem // Enumerate immediate subdirectories of the root:
>>"temp1.txt" (
    for /D %%D in (".\*.*") do @(
        rem // Skip the rest if current subdirectory is the one to exclude:
        if /I not "%%~nxD"=="pest" (
            rem // Output all files found in the current subdirectory recursively:
            pushd "%%~D"
            for /R %%E in ("*.f") do @echo %%~E
            popd
        )
    )
)

这仅返回文件,但不返回目录;如果您也希望包含此类,请尝试以下代码:

rem // Output the path to the root directory itself:
> "temp1.txt" (for /D %%D in (".") do @echo %%~fD)
rem // Enumerate immediate child files in the root, output them:
>>"temp1.txt" (for %%F in (".\*.f") do @echo %%~fF)
rem // Enumerate immediate subdirectories of the root:
>>"temp1.txt" (
    for /D %%D in (".\*.*") do @(
        rem // Skip the rest if current subdirectory is the one to exclude:
        if /I not "%%~nxD"=="pest" (
            rem // Output the current subdirectory:
            echo %%~fD
            rem // Output all files found in the current subdirectory recursively:
            for /F "eol=| delims=" %%E in ('dir /B /S "%%~D\*.f"') do @echo %%E
        )
    )
)

如果pest 子目录可以位于树中的任何位置,您可以使用这种方法:

@echo off
rem /* Call subroutine with the root directory (the current one), the file pattern
rem    and the name of the directory to exclude as arguments: */
> "temp1.txt" call :SUB "." "*.f" "pest"
exit /B

:SUB  val_dir_path  val_file_pattern  val_dir_exclude
rem // Output directory (optionally):
echo %~f1
rem // Enumerate immediate child files and output them:
for %%F in ("%~1\%~2") do echo %%~fF
rem // Enumerate immediate subdirectories:
for /D %%D in ("%~1\*.*") do (
    rem // Skip the rest if current subdirectory is the one to exclude:
    if /I not "%%~nxD"=="%~3" (
        rem /* Recursively call subroutine with the current subdirectory, the file pattern
        rem    and the name of the directory to exclude as arguments: */
        call :SUB "%%~D" "%~2" "%~3"
    )
)

为了避免子目录也被输出,只需删除命令行echo %~f1

由于这种方法具有递归子例程调用的特点,因此在没有pest 子目录的情况下,性能明显比使用简单的dir /S 命令差。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 2013-12-31
相关资源
最近更新 更多