0

I have the following code:

$reader = [System.IO.File]::OpenText(".\Babytest.txt")
try {
    for(;;) 
    {
    $line = $reader.ReadLine()
    if($line eq $null) {break}
            if($line -notMatch 'BB1') { $line }


    }
}
finally {
    $reader.Close()
}

The way I understand this code, is:

$reader = [System.IO.File]::OpenText(".\Babytest.txt")

-- Opens the test.txt file

for(;;) 
        {
        $line = $reader.ReadLine()
        if($line eq $null) {break}
                 if($line -notMatch 'BB1') { $line }

-- If the line is null= EOF break code Else go into another IF look for all lines where there is no 'BB1' in it, output $line

What I want to do

First of all, this code works, although the IF - notmatch doesn't seem to be working, I still see the lines with BB1 in them in my output to the shell. What am I missing?

How can I write this out to a file? This is kind of more loopy stuff oppose to the pipe stuff, so I'm not sure if something like

|out-file "\\fhnsrv01\home\aborgetti\Documentation\Scripts\Baby Removal Project\babyoutput.txt"

would work...all help is greatly appreciated... I've been researching this all day, but it seems powershell has a learning curve, I'm getting the hang of it, there's just so much you can do...

UPDATE

Example String:

AR|111000111011|500001|1|DavT|2013-09-10 12:03:18|2014-04-07 10:23:09|A25415|3|2013-08-11|2013-08-13|Y|01 |APPROVED|01 |APPROVED|35 |

String with no BB1

AR|111100001BB1|500002|1||2014-04-02 15:30:12|2014-04-04 10:55:54|A32009|3|2014-03-31|2014-04-02|Y|01 |APPROVED|03 |PENDING|34 |

String with BB1

I want to remove the lines like BB1 line

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Hituptony
  • 2,740
  • 3
  • 22
  • 44
  • 1
    you need to use `-eq` not `eq`, and you could use `while(1){}` instead of `for(;;)` if you'd like .. Also, It's bad to do testing on or removal of babies – Cole9350 Apr 08 '14 at 20:57
  • @Cole9350 lol you're a fool, thanks broseidon. I probably cannot pipe that out to an out-file, do i need to handle the output inside the second IF? or after? – Hituptony Apr 08 '14 at 21:00
  • and I still am not matching the lines with BB1 in them! – Hituptony Apr 08 '14 at 21:01
  • Either you are not giving us accurate information, or something is very weird on your system. Per all of the below answers, `-notmatch 'BB1'` should work fine. Is the encoding of the file strange? – latkin Apr 08 '14 at 21:34
  • well i only have 5 lines, 3 of which have BB1 in string, 2 should be returned, but all 5 are returned – Hituptony Apr 08 '14 at 21:39

3 Answers3

1

Using a for loop and a StreamReader to read a text file, although not wrong, is just not a right way to do things in Powershell. Unless you have some kind of critical performance requirement (in which case you shouldn't be scripting), it's much better to use the high-level tools that Powershell affords you.

Get-Content .\Babytest.txt |?{ $_ -notmatch 'BB1' } | Out-File 'BabyOutput.txt'

This should do what you want.

latkin
  • 16,402
  • 1
  • 47
  • 62
  • I put this in a ps1 fle and ran it, it does not take out the lines where BB1 is, nor does it output to a file...am I doing something wrong? – Hituptony Apr 08 '14 at 21:18
  • 1
    Using .NET framework types in PowerShell is more than acceptable. There are times where it's absolutely necessary. In this case, `Get-Content` is a bit more "PowerShell friendly," but I strongly encourage people to use the .NET framework to their advantage. –  Apr 08 '14 at 21:20
  • You don't need to put it in a script, you can just paste it into the console. Does `Get-Content .\Babytest.txt` output all the content you expect? If so, your regex pattern might not be doing what you expect. – latkin Apr 08 '14 at 21:22
  • yes it does print out all contents from the file, I updated with example strings, please take a look. I am not the one who will ultimately be running the script that's why putting it in a file will be useful.. – Hituptony Apr 08 '14 at 21:23
  • @TrevorSullivan I never said anything to the contrary, glad we are on the same page. – latkin Apr 08 '14 at 21:23
  • @latkin see string examples, do i need to change pattern match? – Hituptony Apr 08 '14 at 21:28
  • 1
    @Trevor - Agree with using .Net when it's to your advantage, but this is not one of those times. Get-Content with -ReadCount will outperform the .Net streamreader in this application. – mjolinor Apr 08 '14 at 21:39
  • @mjolinor: Right, hence I said `Get-Content` is more PowerShell friendly. I think we are all on the same page. –  Apr 08 '14 at 21:48
  • @Cole This streams content line by line, it does not read the whole file at once. It would rather difficult to OOM. – latkin Apr 10 '14 at 02:09
  • @Latkin yes I am well aware, and although difficult it has happened to me before. But to say using .Net in powershell is not the way of doing things is just completely false http://stackoverflow.com/questions/4192072/how-to-process-a-file-in-powershell-line-by-line-as-a-stream – Cole9350 Apr 10 '14 at 14:28
1

Try this. It uses native powershell commands, and will actually out-perform your stream reader on large files:

Get-Content .\Babytest.txt -ReadCount 1000 |
 foreach {
  $_ -notmatch 'BB1' |
  Add-Content '\\fhnsrv01\home\aborgetti\Documentation\Scripts\Baby Removal Project\babyoutput.txt'
}

Edit: Using the posted test data-

'AR|111000111011|500001|1|DavT|2013-09-10 12:03:18|2014-04-07 10:23:09|A25415|3|2013-08-11|2013-08-13|Y|01 |APPROVED|01 |APPROVED|35 |',
'AR|111100001BB1|500002|1||2014-04-02 15:30:12|2014-04-04 10:55:54|A32009|3|2014-03-31|2014-04-02|Y|01 |APPROVED|03 |PENDING|34 |'|
set-content ./babytest.txt

Get-Content .\Babytest.txt -ReadCount 1000 |
 foreach {
  $_ -notmatch 'BB1'
}

AR|111000111011|500001|1|DavT|2013-09-10 12:03:18|2014-04-07 10:23:09|A25415|3|2013-08-11|2013-08-13|Y|01 |APPROVED|01 |APPROVED|35 |
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • Strange, Idk what I could be doing wrong...Look at strings, do I need to change my Expression to match? This works just like others work, but none match the BB1 strings and remove them...thank you for your time, keep trying please! – Hituptony Apr 08 '14 at 21:27
  • The character string 'BB1' does not appear in your second example. We need a better explanation of what it is you're trying to filter on. – mjolinor Apr 08 '14 at 21:40
  • I have tried, notmatch on entire numberstring and bb1, but it always outputs the BB1 string – Hituptony Apr 08 '14 at 21:42
  • Are you sure you're not seeing old data in the output file? I updated the answer using your test data, and it appears to work. Are you clearing that output file between tests? – mjolinor Apr 08 '14 at 21:48
0

I would do it like this, but what do I know:

while (($line = $reader.ReadLine()) -ne $null) {
    if($line -notlike "*BB1*")
    {
        $line
    }
}
Cole9350
  • 5,444
  • 2
  • 34
  • 50