【问题标题】:Create directory tree to textfile with exclusions将目录树创建为具有排除项的文本文件
【发布时间】:2016-12-25 22:23:41
【问题描述】:

由于脚本应该从外部驱动器在不同的 Windows 计算机上运行,​​所以到目前为止我已经有了这个可执行的批处理文件: create_list.bat

:: http://www.howtogeek.com/204088/how-to-use-a-batch-file-to-make-powershell-scripts-easier-to-run/
@ECHO OFF
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '%~dpn0.ps1'"
echo+
echo Done! list.txt was created.
echo+
PAUSE

在powershell中执行这一行: create_list.ps1

Get-ChildItem | tree /F /A > list.txt

这很好用。 现在我想排除所有文件夹“VIDEO_TS”和“subs”。我怎样才能做到这一点? 我不固定使用 powershell/cmd,但它应该只需双击大多数较新的 Windows 系统即可运行(因此 .exe 也适合)。

我没有使用纯批处理,因为它会混淆所有特殊字符,例如变音符号 (äöü)。 tree 命令本身不支持更多参数,我对 powershell 完全不了解。 我尝试了 powershell 的 -Exclude 参数,但它要么不起作用,要么我搞砸了。

是否可以通过这种方式排除目录或文件(批处理 + powershell),还是我需要其他方法?

/edit1: 显示树

使用 PowerShell 社区扩展 (PSCX) 中的 show-tree cmdlet

。 "R:\电影\show-tree.ps1" 显示树 "R:\Filme" -MaxDepth 5 >> "R:\Filme\testlist.txt"

在循环中结束,中间有这个错误(我翻译过):

错误调用方法,因为
[System.Collections.ObjectModel.Collection`1[[System.String, mscorlib,
版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089]]]
没有名为“SubString”的方法。
在 R:\Film\show-tree.ps1:136 字符:9
+ $RootRelativePath = $ProviderPath.SubString($d.PSDrive.Root.Length)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

/edit2:Powershell 版本信息

$psversiontable

名称值
---- -----
PS版本 4.0
WSManStackVersion 3.0
序列化版本 1.1.0.1
CLRVersion 4.0.30319.42000
构建版本 6.3.9600.17400
PSCompatibleVersions {1.0、2.0、3.0、4.0}
PSRemotingProtocolVersion 2.2

解决方案

从另一个批处理文件从aschipfl's answer 调用脚本:

chcp 1252
CALL aschipfl.bat >> list.txt

【问题讨论】:

  • 您能否澄清一下,您需要排除所有目录,还是只排除您提到的两个文件夹? (无论哪种方式在 PS 中都很容易,但方法不同)
  • 您要按名称还是按完整路径排除文件夹?
  • 抱歉不够精确。我想排除名为“VIDEO_TS”的所有文件夹(和子文件夹/它们的内容)。同时我发现了一个不错的脚本show-tree.ps1,它似乎可以做我想做的事情,但我不知道如何让它运行。如果我通过".\show-tree R:" 调用它,则不会发生任何事情,甚至不会出现错误。
  • 该文件中的第 38、41、44、45、155、156、157、158 和 159 行提供了示例命令。那些从驱动器号级别递归的命令,(多个例如),看起来不像你正在尝试的代码!
  • 是的,我已经看过示例,但是一个错误告诉我该资源不包括在内,但可用。我应该使用“.\show-tree”。我将脚本修改为点包含 show-tree.ps1 并且它可以工作,但我只是得到一个运行或多或少无休止的命令窗口,而且我越来越多 ||||里面的人物。在 R:\ 上没有创建输出文件,我的命令是:. R:\Filme\show-tree.ps1 show-tree R:\Filme -MaxDepth 5 >> testlist.txt

标签: windows powershell batch-file


【解决方案1】:

这是一个使用递归的纯 解决方案:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Comma-separated list of quoted exclusions for directories:
set _DEXCL="VIDEO_TS","subs"
rem // Comma-separated list of quoted exclusions for files:
set _FEXCL=
set "_FILES=" & rem // (set to non-empty value to include files as well)

rem // Global ariable indicating current directory level used for indent:
set /A "$LEVEL=0"

set "ITEM=%~1" & rem // (first command line argument specifies root directory)
rem // No root directory has been specified, so use current directory:
if not defined ITEM set "ITEM=."
rem // Check given root directory for existence and quit script if not found:
if not exist "%ITEM%\" exit /B 1 & rem (trailing "\" to not find files)
rem // Check given root directory against wild-cards and quit if some occur:
set "FLAG=#" & for %%J in ("%ITEM%") do if "%%~J"=="%ITEM%" set "FLAG="
if defined FLAG exit /B 1

rem // Process root directory in sub-routine:
call :PROCESS "%ITEM%"

endlocal
exit /B


:PROCESS  val_dir_path
rem // Display name of provided directory:
set "PTH=%~nx1"
setlocal EnableDelayedExpansion
call :INDENT PAD %$LEVEL%
echo(!PAD!!PTH!
endlocal
rem // Increase indent:
set /A "$LEVEL+=1"
rem // Process all sub-directories:
for /D %%D in ("%~1\*") do (
    rem // Check iterated directory against exclusion list:
    set "FLAG="
    for %%E in (%_DEXCL%) do (
        if /I "%%~nxD"=="%%~E" set "FLAG=#"
    )
    rem // Process iterated directory in sub-routine recursively:
    if not defined FLAG (
        call :PROCESS "%%~D"
    )
)
rem // Process all files in case they are to be included:
if defined _FILES (
    for %%F in ("%~1\*.*") do (
        rem // Check iterated file against exclusion list:
        set "FLAG="
        for %%E in (%_FEXCL%) do (
            if /I "%%~nxF"=="%%~E" set "FLAG=#"
        )
        rem // Display name of iterated file:
        if not defined FLAG (
            set "FILE=%%~nxF"
            setlocal EnableDelayedExpansion
            call :INDENT PAD %$LEVEL%
            echo(!PAD!!FILE!
            endlocal
        )
    )
)
rem // Decrease indent:
set /A "$LEVEL-=1"
exit /B


:INDENT  rtn_string  val_number
rem // Build indent string consisting of spaces:
setlocal EnableDelayedExpansion
set "IND="
for /L %%I in (1,1,%~2) do set "IND=!IND!  "
endlocal & set "%~1=%IND%"
exit /B

【讨论】:

  • 谢谢!这很好用。我什至不知道,纯批次是可能的。虽然现在我遇到了特殊字符的问题 - 尤其是变音符号(äöü):-/ 已经尝试过类似chcp 命令的东西。也许我需要另一批来运行它并替换字符。
  • 您的意思是排除项包含此类特殊字符?好吧,我可以想象将排除字符串放在文本文件中会有所帮助(比如Dexcl.txt,在单独的行中包含VIDEO_TSsubs),因此它们的读取方式与目录树相同(错误) :setlocal EnableDelayedExpansionset "_DEXCL=" & for /F usebackq^ delims^=^ eol^= %%L in ("%~dp0Dexcl.txt") do set _DEXCL="!_DEXCL!","%%~L"endlocal & set _DEXCL=%_DEXCL%
  • 不,幸运的是排除不包含特殊字符,但输出文本文件确实包含错误或不包含 äöü 应该存在的字符。 tree /a >> list.txt 在 cmd 中给出了错误的编码变音符号,但它在 powershell 中有效。这就是我使用 powershell 的原因。
  • 啊,我明白了。你试过chcp 437吗?还有chcp 850chcp 1250?
  • 我之前只尝试过chcp 850 1252 和 65001 - 没有任何变化。现在我又测试了 437 和 1250 以及其他的。这次chcp 1252 成功了!它必须与我的新设置有关:使用chcp 1252 CALL aschipfl.bat >> liste.txt 创建一个文件 aschipfl_start.bat,并且包含您的脚本的 aschipfl.bat 保持不变。
【解决方案2】:

您必须在 Get-ChildItem

中使用 Exclude 参数

在这种情况下使用下面的代码:

Get-ChildItem E:\Source_Test -Exclude "subs","video_ts" | tree /F /A > list.txt 

这将按要求完成您的工作。

希望对你有帮助。

【讨论】:

  • 这是我尝试过的事情之一,但不幸的是它对我不起作用。我仍然得到tree /F /A 的完整未过滤输出。
  • 能分享一下目录列表吗?我想知道文件夹的样子。是否有任何额外的空间和所有。因为这在我的本地非常有效。
  • 是这样的:pastebin.com/6pwu9JeX 用这个 create_list.ps1 创建:Get-ChildItem R:\Filme -Exclude "subs","video_ts" | tree /F /A > list.txt 不区分大小写,已经尝试过了。
  • 好的,在这种情况下,您必须首先使用递归从 get-childitem 中过滤掉。试试这个然后Get-ChildItem E:\Source_Test -Recurse -Exclude "subs","video_ts" | tree /F /A > list.txt
  • 我添加了-Recurse,但它完全没有改变。仍然与我在批处理中纯粹运行 tree /F /A > list.txt 时的输出相同。
猜你喜欢
  • 2011-05-16
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
相关资源
最近更新 更多