header
header Register : : Login header
header
divider
menuleft
menuright
submenu
left

[August 25th, 2008] Check the home page regarding PowerShell related news from a brand new sponsor: Idera

deleting 2nd blank line
Last Post 10 Jun 2008 10:13 PM by kctElgin. 7 Replies.
Printer Friendly
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
04 Jun 2008 12:18 AM  

I am trying to find a simple way to change multiple blank lines into one.  I've got multiple ways of deleting all blank lines, but I can't see a way to do this without writing code to set a switch on blank line and delete everything till next non-blank line, reset the switch and etc.  Testing for "\n\n" never matches anything, at least using get-content.

kct

kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
05 Jun 2008 06:18 PM  

$filename = Get-Item textFile
$singleLine = [System.IO.File]::ReadAllText($filename.fullname)
# $content = $singleLine -creplace "(?s)\r\n(\s*)\r\n(\s*)\r\n", "`r`n"
# $content = $singleLine -creplace "\r\n\r\n\r\n", "`r`n`r`n"
$content = $singleLine -creplace "(\r\n){3,}", "`r`n`r`n"
I've managed to find a way to just get rid of multiple blank lines, but I have struggled to find a method on removing the last line if it is blank. I can't figure out how to truncate array by a line other than doing a foreach and copy line to line stopping at length - 1. Scripting guys had VBscript, which I don't see how to translate.

Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\scripts\test.txt", ForReading)
strFile = objFile.ReadAll
objFile.Close
intLength = Len(strFile)
strEnd = Right(strFile, 2)
If strEnd = vbCrLf Then
    strFile = Left(strFile, intLength - 2)
    Set objFile = objFSO.OpenTextFile("C:\scripts\test.txt", ForWriting)
    objFile.Write strFile
    objFile.Close
End If
halr9000User is Offline
PowerShell MVP, Site Admin
Basic Member
Basic Member
Posts:335
Avatar

--
05 Jun 2008 06:50 PM  
$foo | foreach-object { $_ -replace "\s+" }

Pass an array of strings, check each one for the pattern "\s+" which means "one or more whitespaces". Leaving off the second parameter to -replace replaces the item in the pipeline with...nothing. Does that help?
Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast
Author, TechProsaic
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
05 Jun 2008 07:48 PM  

that is where I started to get rid of the blank lines, but decided a little white space wouldn't hurt and found the example in the PS Cookbook for multiple line searches.  However that left me with the requirement to delete any trailing blank lines.  It looks so simple, IF ($file[-1] = "\s*") then $file.length = $file.length-1, only it does not work.  I understand what the scripting guys did in vbscript, just drop the EOF marker before the CRLF and the blank line is gone.  What I would really like to understand is how to get line 53 removed from an array of 100.  If I can identify the element I should be able to remove it and close up ranks.  I guess part of the problem is I'm trying to find a "neat" way of doing this in PowerShell rather than something along the lines of  for x = 1 to $fileLength - 1 ; $newfile[x] = $file[x].

Another thing I seemed to have found, but not understood, is that an array object and an arraylist object are different, or have different properties.  I had been trying to figure out remove and removerange, but never got anything working.

Thanks for asking

kct

halr9000User is Offline
PowerShell MVP, Site Admin
Basic Member
Basic Member
Posts:335
Avatar

--
05 Jun 2008 07:56 PM  

See the show notes for my podcast ep 23.  First item under the Tips section.

Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast
Author, TechProsaic
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
06 Jun 2008 08:52 PM  

I ended up going down the lines of solution #3 and never quite getting it to work.  I had thought I had already tried the first solution as well, but my guess is that I did the test using "" instead of $null.  One of the joys of mulitple languages is that you use the wrong syntax, NULL, and then move on to something else while muttering how stupid the language is.  Then PS books have index of $null, not NULL so once you know what to do, it is all obvious. 

I had to enhance the solution once it worked by marching backwards through multiple lines.  Today's fight has been with match and contains working with "\s" whether * neccesary and why empty line returned false to both \s and \S.  Are those not opposites?

 

 

Please let me know if you see anything that can be improved. It actually is running and doing what I want. Only a few more enhancements to go.

    foreach ($OrigFile in Get-ChildItem -name) 
    {
    $filename = Get-Item $OrigFile
    $singleLine = [System.IO.File]::ReadAllText($filename.fullname)
    $singleLine = $singleLine -creplace "(\r\n){3,}", "`r`n`r`n"
    $TempName = [System.IO.Path]::GetRandomFileName()
    $singleLine | out-file -filepath $TempName
    $NewFile = get-content $TempName
    $loop = -1
    $answer = Read-Host "processing $newFile"
    while ($loop -gt -10)
        {
        if ($NewFile[$loop] -notmatch "\s") {
            $NewFile[$loop] = $null
            }
        else {
            Write-Host "Not empty"
            }
        write-host "$loop `t $NewFile[$loop]"
        $loop = $loop - 1
        }
    $ProcName = $OrigFile -replace ("`.prc", "")
    $NewFile = $NewFile | 
            foreach {$_ -replace ( "sp_", "spWW_Conv_")
        } | foreach {$_ -replace ( "QUOTED_IDENTIFIER OFF", "QUOTED_IDENTIFIER ON")
        } | foreach {$_ -replace ( 'numeric\(9,0\)', "dbo.seq_nbr")
        } | foreach {$_ -replace ( "@clnt_nbr", "dbo.clnt_nbr")
        } | foreach {$_ -replace ( "\bchar\b", "nchar")        
        } | foreach {$_ -replace ( "\bvarchar\b", "nvarchar")
        } | foreach {$_ -replace ( "\bas\b", "$CommentBlock")
        } | foreach {$_ -replace ("\t", ( " " * 4 ))
        }
    $ConvertedName = $OrigFile -replace ( "sp_", "spWW_GApps_")
    $NewFile | out-file -filepath $ConvertedName
    }

kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
06 Jun 2008 09:04 PM  
Here is the actual change I worked on today.

    $loop = 0
    while ($TRUE){
        $loop = $loop - 1
        $ScriptLine = $NewFile[$loop]
        if ($ScriptLine -match "\bend\b" -or $ScriptLine -match "ansi_nulls"){
            break
        } elseif ($ScriptLine -match "\breturn\b*"){
            break
        } elseif ($ScriptLine -notmatch "\s") {
            $Newfile[$loop] = $null
        }
    } #end while
kctElginUser is Offline
New Member
New Member
Posts:24
Avatar

--
10 Jun 2008 10:13 PM  

Option 1 - Set the item to $null.  This does not actually remove the item, but for most purposes it serves well. $servers[3] = $null

$null seems to work on display, but outputing text file has all the lines set to null back again.

Option 2 - Create a new collection which is a subset of the first.  Drawback here is double the memory as the collection is copied in place.   $servers = $servers -ne “itemthatyouwantremoved”

Problem here is that I want multiple blank lines changed to one blank line and then remove all blank lines from end of file.

Option 3 - Use system.collection.arraylist instead of a generic array.  More steps, but the item or items are removed, and it much more efficient than option 2.  The Scripting Guys explain it well in one of their PowerShell tips of the week. $servers = new-object system.collection.arraylist; $servers.Remove(”item”)

Created the arraylist, but then get-content converted it back to system.object which did not have a remove method.  removerange would be preferred as I need to distinguish by place in file.

As a side issue, how would I read a line and then write the line to a different array?  Will $NewArray = $_ or $NewArray.add($_) work in conjunction of test for current line is blank, last line was blank, skip, else copy line.

You are not authorized to post a reply.

Active Forums 4.1
right
   
footer Sponsored by Quest Software • SAPIEN Technologies • ShellTools, LLC • Microsoft Windows Server 2008 footer
footer