2014-03-12 71 views
2

我需要一個Windows Cli中的等效方法來做我能夠在Linux/UNIX中通過管道顯示唯一值的功能。等效於「sort -u」的DOS命令

我不認爲有這樣一個命令,從我能收集到的東西,所以有另一種方式來做到這一點?

我必須acheieve是列出多個目錄中的文件(無論它們是否存在以及我目前使用dir)。腳本(用於請求應用程序)工作的方式使用多個來源構建目錄列表,隨後根據平臺是Windows還是UNIX來執行命令,但這裏的危險是列表中可能存在重複的目錄,並且這會在另一端扭曲結果。

處理這個問題的最簡單方法是在源代碼處執行,即運行原始命令。所以在Linux中,命令結構或多或少:

find [dir] [dir] [dir] | grep file_name | sort -u 

做同樣在Windows中顯然是更加困難考慮到:

  • 它必須是原生只讀命令/腳本字符串你將一個標準的cmd.exe提示符下使用
  • 我不能在此上
  • 運行主機上安裝任何東西,我不能創建臨時文本文件的過程
的一部分

我可能塞了。

回答

0
@ECHO OFF 
SETLOCAL ENABLEDELAYEDEXPANSION 
(
SET "line=" 
FOR /f "delims=" %%a IN ('sort q22351713.txt') DO (
IF "!line!" neq "%%a" ECHO(%%a 
set "line=%%a" 
) 
)>newfile.txt 

GOTO :EOF 

我用一個名爲q22351713.txt的文件來測試。 可生產newfile.txt

不防彈

總是更好的解釋一下原來的做,而不是以爲這是顯而易見的。

+0

我無法在主機上創建任何文本文件。這將在一個集中式發現工具的多個端點上運行,因此只能使用本機(非PowerShell)命令來讀取命令,並且與其他建議一樣!哦,是的,請告訴我! ;) – delronhubbard

+0

在原文中增加了一些細節。 – delronhubbard

0

髒一批髒...

%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)通過dir1dir2dir3dir 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:\WindowsC:\Windows\System32\cmd.exe,或者更適當地確定您正在掃描的系統的正確位置。