Windows Vista Forums
Vista Forums Home Join Vista Forums Donate Vista Tutorials Tags

Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
Register at Vista forums...the world biggest Windows Vista resource Join Vista Forums Now

Go Back   Vista Forums > Microsoft Technical Newsgroups > PowerShell

Getting the next line after a string

Closed Thread
 
Thread Tools Display Modes
Old 10-17-2006   #1 (permalink)
Marco Shaw
Guest
 
Posts: n/a

Getting the next line after a string

I'm looking to search a file for "string X", but actually output the next
line (or 2).

The select-string cmdlet doesn't seem to have this functionality... Is
there an existing cmdlet that can do this?

Marco


 
Old 10-17-2006   #2 (permalink)
klumsy@xtra.co.nz
Guest
 
Posts: n/a

Re: Getting the next line after a string


Marco Shaw wrote:
> I'm looking to search a file for "string X", but actually output the next
> line (or 2).
>
> The select-string cmdlet doesn't seem to have this functionality... Is
> there an existing cmdlet that can do this?
>
> Marco


you can do it in powershell natively with expressions.. the first thing
is to seperate the strings into a string for each line (however
get-content should do that).. but lets start with an example

so
$a = ("some string `r`n another string","something" ,"this is another
ratdog","next" )

$a | % { $_.split("`r`n") } will ensure that the embed carriage return
gets seperated into two strings

then pipe that to another foreach expression that uses the logic you
want

$a | % { $_.split("`r`n") } | % { if ($outputnext) { $_} ; $outputnext
= ($_ -match "another*" )}

so in your case you could just do

get-content "myfile.txt" | % { if ($outputnext) { $_} ; $outputnext =
($_ -match "another*" )}

maybe there is a more elegant way in the language to do this, and maybe
there even is a commandlet, or cmdlet option that can do it for you,
but the point is powershell is also a language so where the
functionality of build in cmdlets lacks, you can write a small
(ussually one liner) of script that can fufill your needs.

Karl

 
Old 10-18-2006   #3 (permalink)
Bruce Payette [MSFT]
Guest
 
Posts: n/a

Re: Getting the next line after a string

You can use the switch statement to do this. When the switch statement is
matching against a collection of lines, it places the loop enumerator into
the variable $switch. This let's you use this variable to read the next
element from the enumeration. Let's look at an example:

We'll write a function using the switch statement that shows how to do this
called Get-LineAfterPattern. First we'll build a collection of lines using a
here string an the Split() method.

PS (29) > $lines = @'
>> aaaa
>> bbbb
>> ccc1
>> dddd
>> eeee
>> aaaa
>> bbbb
>> ccc2
>> dddd
>> eeee
>> '@.Split("`n")
>>


Now we want to get the lines that appears after the row of b's. The result
should look like this:

PS (30) > Get-LineAfterPattern b+ $lines
ccc1
ccc2

Here's what this function looks like:

function Get-LineAfterPattern ($pat, $strings) # take 2 args - the
pattern and the string collection
{
switch -regex ($strings) # search the
strings using regex
{
$pat { # if
the pattern matches
if ($switch.MoveNext()) # and there is
a next line
{
$switch.Current # emit
that line
}
}
}
}

-bruce

--
Bruce Payette [MSFT]
Windows PowerShell Technical Lead
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.

Visit the Windows PowerShell Team blog at:
http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:
http://www.microsoft.com/technet/scr.../hubs/msh.mspx
My Book: http://manning.com/powershell

<klumsy@xtra.co.nz> wrote in message
news:1161108626.256892.111070@e3g2000cwe.googlegroups.com...
>
> Marco Shaw wrote:
>> I'm looking to search a file for "string X", but actually output the next
>> line (or 2).
>>
>> The select-string cmdlet doesn't seem to have this functionality... Is
>> there an existing cmdlet that can do this?
>>
>> Marco

>
> you can do it in powershell natively with expressions.. the first thing
> is to seperate the strings into a string for each line (however
> get-content should do that).. but lets start with an example
>
> so
> $a = ("some string `r`n another string","something" ,"this is another
> ratdog","next" )
>
> $a | % { $_.split("`r`n") } will ensure that the embed carriage return
> gets seperated into two strings
>
> then pipe that to another foreach expression that uses the logic you
> want
>
> $a | % { $_.split("`r`n") } | % { if ($outputnext) { $_} ; $outputnext
> = ($_ -match "another*" )}
>
> so in your case you could just do
>
> get-content "myfile.txt" | % { if ($outputnext) { $_} ; $outputnext =
> ($_ -match "another*" )}
>
> maybe there is a more elegant way in the language to do this, and maybe
> there even is a commandlet, or cmdlet option that can do it for you,
> but the point is powershell is also a language so where the
> functionality of build in cmdlets lacks, you can write a small
> (ussually one liner) of script that can fufill your needs.
>
> Karl
>



 
Old 10-20-2006   #4 (permalink)
Alex K. Angelopoulos [MVP]
Guest
 
Posts: n/a

Re: Getting the next line after a string

"Bruce Payette [MSFT]" <brucepay@microsoft.com> wrote in message
news:eNwOXso8GHA.1188@TK2MSFTNGP05.phx.gbl...
> You can use the switch statement to do this. When the switch statement is
> matching against a collection of lines, it places the loop enumerator into
> the variable $switch. This let's you use this variable to read the next
> element from the enumeration. Let's look at an example:


Piggybacking on Bruce's comments:
All of the looping constructs have loop enumerators exposed in a variable
that uses the keyword as a name. So you can also do the same general thing
with a foreach loop.

Given a file whose path or FileInfo reference is in variable $f, and which
contains data you want to examine, returning the line immediately following
an occurrence of "String X", here is what you could do:

foreach($line in Get-Content $f){
if($line -ilike "*string X*"){
if($foreach.MoveNext()){ $line }
}
}

Some interesting bits to this:

+ The $foreach and similar enumerators are instances of the private nested
class System.Array+SZArrayEnumerator (not interesting, but potentially
useful).
+ MoveNext() returns a boolean value depending on whether there _was_ a next
item to jump to. This makes it easy to not do output if String X is the last
line in the file.
+ This does not test the line you've moved to. If the line you want to print
also contains "String X" it doesn't get tested. This is probably what you
want, but if you don't it will take some extra work using a
do{...}while(condition) loop.


 
Old 10-20-2006   #5 (permalink)
Marco Shaw
Guest
 
Posts: n/a

Re: Getting the next line after a string

> get-content "myfile.txt" | % { if ($outputnext) { $_} ; $outputnext =
> ($_ -match "another*" )}


Tried this:
get-content "c:\file.txt"|%{if($outputnext){$_};$outputnext=($_ -match
"*Latest reply*")}

But I get this several times:
+ get-content "c:\file.txt"|%{if($outputnext){$_};$outputnext=($_ -match
<<<< "*Latest reply*")}
The '-match' operator failed: parsing "*Latest reply*" - Quantifier {x,y}
following nothing..
At line:1 char:70

I can't put a wildcard at the beginning of the string "Latest reply"?

I'll try some of the other suggestions also.

Marco


 
Old 10-20-2006   #6 (permalink)
Alex K. Angelopoulos [MVP]
Guest
 
Posts: n/a

Re: Getting the next line after a string

Sure you can. But -match is a regular expression match, and your expression
isn't valid. That's because in regex matching, "*" means "match zero or more
occurrences of the preceding character" - and there is no preceding
character. Since regular expressions are not anchored to ends of a string by
default, you can just omit the initial "*". On the other end of your
sequence, the reply* means "match 'repl' and zero or more of the character
'y'. So even if you had "Latest reply*" it would be matching things like:
Latest repl
Latest replyyyyyy
I suggest doing either of the following:
(1) Use a regular expression literal match:
$_ -match "Latest reply"
(2) Use a like match, which has the wildcarding syntax you expected:
$_ -like "*Latest reply*"

"Marco Shaw" <marco@Znbnet.nb.ca> wrote in message
news:uVzSF1G9GHA.3264@TK2MSFTNGP04.phx.gbl...
>> get-content "myfile.txt" | % { if ($outputnext) { $_} ; $outputnext =
>> ($_ -match "another*" )}

>
> Tried this:
> get-content "c:\file.txt"|%{if($outputnext){$_};$outputnext=($_ -match
> "*Latest reply*")}
>
> But I get this several times:
> + get-content "c:\file.txt"|%{if($outputnext){$_};$outputnext=($_ -match
> <<<< "*Latest reply*")}
> The '-match' operator failed: parsing "*Latest reply*" - Quantifier {x,y}
> following nothing..
> At line:1 char:70
>
> I can't put a wildcard at the beginning of the string "Latest reply"?
>
> I'll try some of the other suggestions also.
>
> Marco
>



 
 
Closed Thread

Thread Tools
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
Write every line except the one with first occurence of a string Karch PowerShell 5 01-14-2008 06:58 AM
end of line while processing a string token issue hectoritnt PowerShell 6 09-28-2007 01:22 PM
Search for string in CSV and delete line if string found in line sherlock PowerShell 2 07-02-2007 03:42 PM
String PRODUCT_NAME was not found in string table Extracampine Vista General 3 02-12-2007 06:15 AM
Encountered end of line while processing a string token Marco Shaw PowerShell 5 11-15-2006 06:36 AM








Vistax64.com is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media 2005-2008

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49