Process HereString line by line

833 Views Asked by At

I would like to define a HereString then work with it line by line. Initially I figured the lines would be innate in the HereString, so I could foreach ($line in $hereString), and when that didn't work I tried Get-Content $hereString. No joy in either case. The goal is just to work on a bit of code that will eventually manipulate entire text files, so I could quickly convert to using a small example text file while implementing this, but now I am curious if HereStrings even CAN be worked with line by line, without splitting somehow.

4

There are 4 best solutions below

1
On BEST ANSWER

Since your intent is to use this to process files, I'd start with something like this:

$file = 'c:\testfiles\testfile1.txt'

$textdata = 
@'
Line1
Line2
Line3
'@

$textdata | Set-Content $file

$lines = Get-Content $file

foreach ($line in $lines) {}

Now you're testing in the same environment that you'll be working with in production, and you can experiment with different I/O methods as well as different data parsing and manipulation methods. Knowing how to do this will become more important from a performance standpoint as the size and number of files involved scales upwards.

0
On

Your could do this:

foreach ( $line in $herestring.replace("`r`n", "`n").split("`n") ) { 
    '>>>{0}<<<' -f $line; 
    }

The replace() being there to replace Windows' CRLF line terminator with just a new line...

0
On

As PetSerAl suggests, the simplest solution is probably using the -split operator:

foreach($line in $herestring -split '\r?\n')
{
    # process $line here    
}

using the pattern \r?\n will match both \r\n (Windows-style newline) and \n (Unix-style newline)

1
On

note that both 'Split' and 'ForEach' cause the entire file to be parsed first before processing begins. if the file will be very large, there will be a delay before processing starts and memory can become a concern.

another alternative comes from .NET in the form of a textreader...

$rdr = new-object System.IO.StreamReader('c:\path\to\file.txt')
while (!$rdr.EndOfStream) {
    $line = $rdr.ReadLine()
    ## do processing on the line ##

}

In the above, each time the ReadLine method of the StreamReader is called, it advances to the next line. The above is most efficient and gives you a chance to break out early if something is found that is not liked in the file.

You can look at the details of the StreamReader here.