髒一批髒...
%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