2015-11-07 73 views
1

我必須使用批處理文件在.log文件(純文本)中查找字符串。
它需要找到:
(會話ID令牌:

如果要是發現它打印行的其餘部分開始在,並在
結束請幫我做這個Findstr查找字符串並打印出

+0

它必須是批處理文件,還是可以使用PowerShell?(PowerShell是更簡單,幾乎都更強大,因此是更好的方式來進行,除非有一個很好的理由,堅持批處理文件爲您的方案)。 – JohnLBevan

+0

我想用一批,但你的ID與電源外殼腳本,我會很高興回答。 XD – StratHaxxs

回答

2

這裏的.Bat解決方案:

set filename="c:\temp\demo.txt" 
set strToFind="session id" 
set result="Not Found" 
for /f "tokens=2 delims=()" %%A in ('findstr %strToFind% %filename%') do (set result=%%A) 
echo.%result% 

說明:

  • for /f -loop通過一個命令的輸出(見http://ss64.com/nt/for_cmd.html
  • " ......我們使用括號作爲分隔符delims=()";即session id (hello mum) demo =>session idhello mumdemo。注意:這不是很聰明,所以不能識別括號內的哪一個方向,或者它們在哪裏(即它們是在session id之前還是之後)。希望這仍然令人滿意。
  • "tokens=2 ... " - 我們知道在我們不感興趣的第一個括號(即session id)之前會有一些內容;那麼有第一個支架(希望是開場),我們希望所有的內容,直到下面的支架(希望是一個關閉支架);之後我們不關心任何事情。所以我們想捕捉前兩個結果然後停止搜索(我們不關心第一個結果;但是我們必須先找到第一個結果才能繼續搜索)。因此,我們需要2個令牌/結果。
  • %%A in (' ... ') - 反過來每個標記分配到參數%%A
  • findstr %strToFind% %filename% - 從文本文件返回所有行包含給定的字符串(strToFind)(可變filename路徑)。
  • do ( ... ) - 通過每個令牌循環,在括號
  • set result=%%A執行操作 - 的發現令牌分配給result覆蓋任何以前瓦萊斯(即,從前面的迭代)。

示例文件(demo.txt):

demo text 
demo text session id 
demo text 
demo text (not this one) 
demo text 
demo text session id (this is something) blah 
demo text 
demo text session id again 
demo text (or this one) 
demo 

下面是PowerShell相同(允許多個結果)

[string]$fn = "C:\temp\demo.txt" 
[string[]]$results = get-content -Path $fn ` 
    | ?{$_ -like '*session id*(*)*'} ` 
    | %{$_ -replace ".*Session ID.*\((.*?)\).*",'$1'} 
$results 

說明:

  • [string[]]$results = - 將以下操作的結果分配給results變量(定義爲字符串數組)。
  • get-content -Path $fn - 獲取文件的內容,返回一個字符串數組,其中的每一項都是文本文件中的一行(因爲我們沒有指定-raw該文件的新行字符被視爲分隔符,因此多個字符串而不是一個大字符)
  • | ?{ ... } - 對於數組中的每個字符串,篩選給定條件爲真的字符串。 (管道)說要採用前面的陳述的結果並對這些陳述應用以下邏輯。 ?{ ... }where-object {的簡寫... }
  • $_ -like '*session id*(*)*' - 條件是一個字符串,其中包含文字session id(後面可能包含幾個字符)括號,其中可能包含其他字符,並且可能後跟其他字符。 $_表示數組中的當前項目(即在這種情況下,我們正在搜索的字符串)。 *-like條件的通配符,表示存在任何類型的零個或多個字符。
  • | %{ .. } - 這說的是將給定的命令應用於結果(在之前的where-object之後剩下的那些)。 %{ ... }foreach-object{ ...的簡寫... }
  • $_ -replace ".*Session ID.*\((.*?)\).*",'$1' - 這表示使用正則表達式搜索每個字符串,並用字符串session id後面的括號之間的內容替換它的內容。

該正則表達式的進一步的細分:

  • .* - 任何字符(.
  • Session ID的零和或多個(*) - 隨後的特定字符串session id(的powershell是不區分大小寫的默認情況下;我們早些時候使用-clike進行區分大小寫的比較)。
  • .* - 之後出現零次或多次出現的任何字符
  • \( - 後面跟一個左括號。 \被用作(是一個特殊字符(即具有語法意義/功能),所以我們添加斜線以逃避該字符/將其視爲文本括號而不是具有任何特殊含義。
  • (.*?) - 後跟零個或多個任意字符。圍繞這個的括號表示我們想要捕獲輸出(這是後面提到的$1; 1,因爲這是我們的正則表達式中的第一個捕獲語句;如果有更多,下一個將被引用爲$2,依此類推。 .*?,使捕獲「非貪婪」 - 即只捕捉到第一閉括號,而不是到最後,所以(hello)mum)將有$1=hello而不是$1=hello)mum
  • \) - 隨後關閉parenthisis
  • .* - 後跟零個或多個任意字符
+1

你會恨我此,可以使用批處理可我第一後變量設置爲一切?例如:會話ID是令牌:blablabla:4348237493287收件人:blablabla:4348237493287? @JohnLBevan – StratHaxxs

+0

當然;用':'替換分隔符('()')。添加解釋上述結果現在,以幫助更好地解釋它... – JohnLBevan

+0

'設置strToFind =「(會話ID令牌:」 組結果=「未找到」 FOR/F「令牌= 2個delims = :)」%在%A( 'FINDSTR%strToFind%%文件名%')不要(設結果= %% A)'是我的代碼,但結果:29 ...任何幫助嗎? @JohnLBavan – StratHaxxs