Reputation: 19
I have to use a batch file to find a string in a .log file (Plain Text).
It needs to find:
(Session ID is token:
And if if finds it print the rest of the line starting at the ( and ending at the )
Please help me do this.
Upvotes: 1
Views: 2563
Reputation: 24410
Here's the .Bat
solution:
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%
Explanation:
for /f
-loop through the output of a command (see http://ss64.com/nt/for_cmd.html)"
...delims=()"
we're using brackets as delimiters; i.e. session id (hello mum) demo
=> session id
, hello mum
, demo
. NB: this isn't that clever, so won't recognise which way around the brackets occur, or where in the string they are (i.e. whether they're before or after session id
). Hopefully that's still satisfactory."tokens=2
..."
- we know there'll be some content before the first bracket (i.e. session id
) which we're not interested in; then there's the first bracket (hopefully the opener), and we want all content until the following bracket (hopefully a close bracket); we don't care about anything after that. So we want to capture the first two results then stop searching (we don't care about the first result; but we have to find that first in order to move on to the second one). As such, we want 2 tokens / results.%%A in ('
...')
- Assign each token in turn to the parameter %%A
findstr %strToFind% %filename%
- return all lines from the text file (path in variable filename
) which contain the given string (strToFind
).do (
...)
- loop through each token, performing the operation in the bracketsset result=%%A
- assign the found token to result
overwriting any previous vales (i.e. from earlier iterations).Sample File (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
Here's the same in PowerShell
(allows for multiple results)
[string]$fn = "C:\temp\demo.txt"
[string[]]$results = get-content -Path $fn `
| ?{$_ -like '*session id*(*)*'} `
| %{$_ -replace ".*Session ID.*\((.*?)\).*",'$1'}
$results
Explanation:
[string[]]$results =
- assign the results of the following operation to the results
variable (defined as an array of strings). get-content -Path $fn
- get the contents of the file, returning an array of strings where each item in the array is a line from the text file (as we didn't specify -raw
the file's new line characters are treated as delimiters, hence multiple strings rather than one big one)| ?{
...}
- for each string in the array, filter for those for which the given condition is true. |
(pipeline) says to take the results of the previous statement and apply the following logic to these. ?{
...}
is shorthand for where-object {
...}
.$_ -like '*session id*(*)*'
- the condition is a string containing the text session id
followed (perhaps several characters later) by brackets, which may contain additional characters, and may be followed by other characters. $_
represents the current item in the array (i.e. in this case the string we're searching). *
is a wildcard for the -like
condition saying where there are zero or more characters of any type.| %{
..}
- This says to apply the given command to the results (those remaining after the earlier where-object
). %{
...}
is shorthand for foreach-object{
...}
.$_ -replace ".*Session ID.*\((.*?)\).*",'$1'
- this says to use the regular expression to search each string and replace its contents with whatever's between the brackets which follow the string session id
.A further breakdown of the regex:
.*
- zero or more occurrences (*
) of any character (.
)Session ID
- followed by the specific string session id
(powershell is case insensitive by default; we'd have used -clike
earlier for a case sensitive comparison)..*
- followed by zero or more occurrences of any character\(
- followed by an opening parenthesis. \
is used as (
is a special character (i.e. has syntactic meaning/function), so we add the slash to escape this character / have it treated as the text bracket rather than having any special meaning.(.*?)
- followed by zero or more of any character. The brackets around this say we we want to capture the output (this is what the $1
later refers to; the 1
because this is the first capture statement in our regex; were there more the next would be referenced as $2
, and so on. The ?
after .*
makes the capture "non-greedy" - i.e. to capture only to the first close bracket rather than to the last; so (hello)mum)
would have $1=hello
rather than $1=hello)mum
.\)
- followed by a closing parenthisis..*
- followed by zero or more of any character. Upvotes: 2