脏一批脏...
%COMSPEC% /d /v:on /c "(SET LASTLINE=) & (FOR /f "usebackq tokens=*" %L IN (`DIR /b /s /-p dir1 dir2 dir3 dir3 dir2 dir1 "dir with space" ^| %SYSTEMROOT%\system32\find.exe /i "search_file_name" ^| %SYSTEMROOT%\system32\sort.exe`) DO @((IF /i NOT "{!LASTLINE!}"=="{%~L}" ECHO %~L) & SET "LASTLINE=%~L"))"
让我们打破这一点...
%COMSPEC% /d /v:on /s /c "..."
- 你想一个命令,而不是一个批次,我们需要延迟扩展(/v:on
),因此我们使用Windows命令提示符(%COMSPEC%
)的已知可执行文件调用子shell。我们不想运行autoexec.bat(/d
),我们想运行该命令并继续前进,而不是离开交互式shell(/c "..."
)。引用是一个时髦的问题,所以我们尝试了一些“规范”行为(/s
)
SET LASTLINE=
- 清空LASTLINE
环境变量
(...) & (...)
的任何现有内容 - &
前&
后运行一切,一切不管退出第一位的代码。根据需要使用括号来组合命令。
FOR /f "usebackq tokens=*" %L IN (`...`) DO ...
- 运行后引号(usebackq
)之间的命令串,并阅读标准输出(FOR /f
)的每个行中的所有的单词(tokens=*
)到临时变量%L
。
DIR /b /s /-p dir1 dir2 dir3 dir3 dir2 dir1 "dir with space"
- 递归(/s
)通过dir1
,dir2
,dir3
和dir with space
,文件到标准输出(/b
)只打印出完整路径不胜枚举。如果已设置(/-p
),则不需要按键来分页输出。需要注意的是,由于FOR
弱点是由你来只报价目录用特殊字符(如空格),即不要引用单个词的名字。
... ^| ...
- 管中的第一命令的所述第二的标准输入的标准输出。我们使用^
在FOR
的反引号内转义|
。
%SYSTEMROOT%\system32\find.exe /i "search_file_name"
- 找到标准输入字符串search_file_name
。使用不区分大小写的搜索(/i
)。
%SYSTEMROOT%\system32\sort.exe
- 排序标准输入和输出到stdout。
DO @(...)
- 我们需要运行每行两个命令,所以在括号中,我们组他们。 FOR
通常会在每个命令运行之前打印出来,@
会抑制这一点。
(IF /i NOT "{!LASTLINE!}"=="{%~L}" ECHO %~L)
- 如果我们正在查看的行%~L
与我们存储的行不相同!LASTLINE!
,请打印我们正在查看的行。再次使用不区分大小写的比较(/i
)。我们书夹两个变量与{}
处理空值,我们使用延迟扩展(!LASTLINE!
而不是%LASTLINE%
)每次循环的时间来扩大LASTLINE
,不只是当FOR
命令第一次看到。
SET "LASTLINE=%~L"
- 将我们正在查看的行%~L
存储到变量LASTLINE
中。
如果您无权访问内置环境变量,则可能没有%SYSTEMROOT%
或%COMSPEC%
。将这些替换为C:\Windows
和C:\Windows\System32\cmd.exe
,或者更适当地确定您正在扫描的系统的正确位置。
我无法在主机上创建任何文本文件。这将在一个集中式发现工具的多个端点上运行,因此只能使用本机(非PowerShell)命令来读取命令,并且与其他建议一样!哦,是的,请告诉我! ;) – delronhubbard
在原文中增加了一些细节。 – delronhubbard