none
Removing trailing blank lines in PowerShell

    Question

  • Hi,
    $file = Get-ChildItem "c:\a.txt"
    [System.IO.File]::AppendAllText("$file", '±', [System.Text.Encoding]::Unicode)
    foreach ($str in $file) 
    {
    $content = Get-Content -path $str
    $content | foreach {$_ -replace "±",""} | Set-Content $str
    }
    after running the above script, I get one extra line at the end of the file, how can I remove it?
    or add the "±" without \n .. 
    Thanks!
    Tuesday, October 18, 2011 7:22 AM

Answers

  •  
    This works for me:
    $file = "c:\testfiles\test.txt"
    $in = [System.IO.File]::OpenText($file)
    $text = ($in.readtoend()).trim("`r`n")
    $in.close()
    
    $stream = [System.IO.StreamWriter]$file
    $stream.write($text)
    $stream.close()
    
    You need to provide it wth string arguments, so if you're doing a directory lookup, you want the fullname property of the filleinfo object as the argument.

    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    • Edited by mjolinor Wednesday, October 19, 2011 3:47 PM
    • Marked as answer by Dmmnn Wednesday, October 19, 2011 8:40 PM
    Wednesday, October 19, 2011 3:46 PM
  • I found that New-Item don't add anything at the end so you could overwrite the file with it. For example here I create a file that end with "-" and then i remove it and finally i overwrite it.
    New-Item -ItemType file -Value "lala`r`nEnd.-" -Path texto.txt -for
    (${c:texto.txt} -replace "-","" ) -join "`r`n"|% { ni -itemtype file -Path texto.txt -Value $_ -for}
    
    


    You don't have the necessity to remove a last blank line because it doesn't going to exist.  Alternativelly you could use the ReadAllText method instead of the array concat(I think that this is more efficient):

     

    # Create file
    ni -it file -val "Uno`r`nDos`r`nEnd." -p texto.txt -for 
    # Append content
    [IO.File]::AppendAllText($pwd.path+"\texto.txt", "-") 
    # Remove the appended content
    ni -it file -path texto.txt -val ([regex]::replace([IO.File]::ReadAllText($pwd.path+"\texto.txt"), "-$","")) -Force 
    

    • Edited by voodoomsr Wednesday, October 19, 2011 8:00 PM second example
    • Marked as answer by Dmmnn Wednesday, October 19, 2011 8:40 PM
    Wednesday, October 19, 2011 4:53 PM

All replies

  • Sorry, I'm not understanding what you are trying to do.  What is that strange character that you are appending?
    [string](0..9|%{[char][int](32+("39826578840055658268").substring(($_*2),2))})-replace "\s{1}\b"
    Tuesday, October 18, 2011 8:44 AM
  • Hi Dmmnn,

    i think the issue is that the when you are adding the character , you are adding it as unicode character.

    if you examine your text file in a textpad or textpa++, you can see that there s a nul character along with your unicode character.

    and when you use replace it is adding up that new line

    you probably have to use regular expressions to remove the unicode character

    Bigteddy,

    he is adding a unicode charater to the text file and then wants to remove that later or replace it

     


    -join("74686979616775313440686F746D61696C2E636F6D"-split"(?<=\G.{2})",21|%{[char][int]"0x$_"})
    http://www.myExchangeWorld.com
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Tuesday, October 18, 2011 9:15 AM
  • thanks for the prompt replies guys,

    the character is not the issue here unfortunately :) it was taken from ascii

    it might very well a string expression, "aaa"

    the issue, from what I've experienced, is that it's added with a new line break after, " \n "

     

    e.g.

    "a

    b

    c

     

    "

    notice the empty line break after character "c"

     

     

     in cygwin you have

    echo "dsafasdf" -n

    where -n automatically does not add the empty trailing line break.

     in cygwin you have

    echo "dsafasdf" -n

    where -n automatically does not add the empty trailing line break.

    • Edited by Dmmnn Tuesday, October 18, 2011 10:20 AM
    Tuesday, October 18, 2011 9:40 AM
  • it actually adds at the end of the text, one space " " + 1 trailing line break

    Tuesday, October 18, 2011 10:31 AM
  • it is actually the set-content which is doing this .

    if you examine with the output without the set-content, you can see this.

     so you have to look for the last carraige return and remove it seperately, if you dont want it.

    thanks

    thiyagu


    -join("74686979616775313440686F746D61696C2E636F6D"-split"(?<=\G.{2})",21|%{[char][int]"0x$_"})
    http://www.myExchangeWorld.com
    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Edited by Thiyagu14 Tuesday, October 18, 2011 10:52 AM update
    Tuesday, October 18, 2011 10:51 AM
  • how? :)

    supposing I use:

    $file.replace("`n","")

    I need to go to the last crlf, and that is my trouble

    I was considering a "backspace" function, or using a some kind of length($file) - 2   -> it would delete the last two characters from my text... but the syntax is killing me in powershell :)

    • Edited by Dmmnn Tuesday, October 18, 2011 12:28 PM
    Tuesday, October 18, 2011 12:19 PM
  • You can try excluding the null lines before you do the set-content:
    $file = Get-ChildItem "c:\a.txt"
    [System.IO.File]::AppendAllText("$file", '±', [System.Text.Encoding]::Unicode)
    foreach ($str in $file) 
    {
    $content = Get-Content -path $str
    $content | foreach {$_ -replace "±",""} | where {$_} | Set-Content $str
    }


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Tuesday, October 18, 2011 1:00 PM
  • i think he wants to remove the last crlf from the file.

    try this Dmnn, there may be a better way, but this what i came up with

    $text = [System.IO.File]::OpenText("input.txt").ReadToEnd()
    $two = $text.substring($text.Length-2,2)
    if ($two -eq "`r`n")
    {
    	$newContent = $text.Substring(0, $text.Length-2)
    	$stream = [System.IO.StreamWriter]"output.txt"
    	$stream.write($newContent)
    	$stream.close()
    }
    
    

     


    -join("74686979616775313440686F746D61696C2E636F6D"-split"(?<=\G.{2})",21|%{[char][int]"0x$_"})
    http://www.myExchangeWorld.com
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Tuesday, October 18, 2011 1:43 PM
  • it didn't work :(

    thanks anyway mjolinor.

    Tuesday, October 18, 2011 2:27 PM
  • did u try the method i posted above? using the streamwriter?
    -join("74686979616775313440686F746D61696C2E636F6D"-split"(?<=\G.{2})",21|%{[char][int]"0x$_"})
    http://www.myExchangeWorld.com
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Tuesday, October 18, 2011 2:31 PM
  • did u try the method i posted above? using the streamwriter?
    -join("74686979616775313440686F746D61696C2E636F6D"-split"(?<=\G.{2})",21|%{[char][int]"0x$_"}) 
    http://www.myExchangeWorld.com
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Method invocation failed because [System.RuntimeType] doesn't contain a method named 'write'.
    At c:\scripts\t.ps1:14 char:15
    +     $stream.write <<<< ($newContent)
        + CategoryInfo          : InvalidOperation: (write:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound
    Method invocation failed because [System.RuntimeType] doesn't contain a method named 'close'.
    At c:\scripts\t.ps1:15 char:15
    +     $stream.close <<<< ()
        + CategoryInfo          : InvalidOperation: (close:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound

    • Edited by Dmmnn Tuesday, October 18, 2011 2:50 PM
    Tuesday, October 18, 2011 2:47 PM
  • p.s.:

    \system32\WindowsPowerShell\v1.0\

    Tuesday, October 18, 2011 2:49 PM
  • can you post your code?
    -join("74686979616775313440686F746D61696C2E636F6D"-split"(?<=\G.{2})",21|%{[char][int]"0x$_"})
    http://www.myExchangeWorld.com
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Tuesday, October 18, 2011 2:54 PM
  • with your stream included:
    # $loc = \\ka2, ..., \\ka101
    # $apname = smsytlicktyanfl, %suffix% @end/trial/done
    clear-Host
    #$file = Get-ChildItem "c:\a.txt"
    $locfile = "\\ka2\igs\App\fig\smsytlicktyanel.es\app.config", "\\ka2\igs\App\fig\smsytlicktyanfl.ed\app.config", "\\ka2\igs\App\fig\smsytlicktyanrl.ee\app.config"
    $ol = New-Object -comObject Outlook.Application 
    $mail = $ol.CreateItem(0) 
    $Mail.Recipients.Add("testmail@testserver.com")
    $Mail.Subject = "PS1 Run-test" 
    foreach ($element in $locfile)
    {
    $s=$s + $element.substring(18,18) + "`n"
    }
    $Mail.Body = "testing this with split" + "`n" + $s
    $Mail.Send()
    foreach ($element in $locfile) 
    {
    [System.IO.File]::AppendAllText("$element", '&', [System.Text.Encoding]::Unicode)
    foreach ($str in $element) 
    {
    $content = Get-Content -path $str
    $content | foreach {$_ -replace "&",""} | Set-Content $str
    $text = [System.IO.File]::OpenText($file).ReadToEnd()
    $two = $text.substring($text.Length-2,2)
    if ($two -eq "`r`n")
    {
    $newContent = $text.Substring(0, $text.Length-2)
    $stream = [System.IO.StreamWriter]
    $stream.write($newContent)
    $stream.close()
    }
    }
    }
    echo "Done`n"
    $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    exit
    Tuesday, October 18, 2011 3:00 PM
  • $newcontent = ($text = [System.IO.File]::OpenText($file).ReadToEnd()).trim("")
    
    $stream = [System.IO.StreamWriter]$file
    $stream.write($newContent)
    $stream.close()
    


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Tuesday, October 18, 2011 3:40 PM
  • Hi mjolinor,

    I tried your stream in this:

     

     

    $file = Get-ChildItem "c:\a.txt"
    
    [System.IO.File]::AppendAllText("$file", '±', [System.Text.Encoding]::Unicode)
    
    foreach ($str in $file) 
    
    {
    
    $content = Get-Content -path $str
    
    $content | foreach {$_ -replace "±",""} | where {$_} | Set-Content $str
    
    }
    
    $newcontent = ($text = [System.IO.File]::OpenText($file).ReadToEnd()).trim("")
    
    $stream = [System.IO.StreamWriter]$file
    
    $stream.write($newContent)
    
    $stream.close($file)
    
    
    
    weird exceptions come as result:

     

    Cannot convert the "C:\a.txt" value of type "System.IO.FileInfo" to type "System.IO.StreamWriter".

    At D:\PSscripts\t.ps1:10 char:40

    + $stream = [System.IO.StreamWriter]$file <<<<

        + CategoryInfo          : NotSpecified: (:) [], RuntimeException

        + FullyQualifiedErrorId : RuntimeException

     

    You cannot call a method on a null-valued expression.

    At D:\PSscripts\t.ps1:11 char:14

    + $stream.write <<<< ($newContent)

        + CategoryInfo          : InvalidOperation: (write:String) [], RuntimeException

        + FullyQualifiedErrorId : InvokeMethodOnNull

     

    You cannot call a method on a null-valued expression.

    At D:\PSscripts\t.ps1:12 char:14

    + $stream.close <<<< ($file)

        + CategoryInfo          : InvalidOperation: (close:String) [], RuntimeException

        + FullyQualifiedErrorId : InvokeMethodOnNull

    Wednesday, October 19, 2011 7:46 AM
  • hi Dmnn,

    to narrow down the issue, can you just copy just one file locally and then use the below script to run.

    run it seperately, instead of being part of the script.

    so, we can narrow down where the issue is:

    $text = [System.IO.File]::OpenText("input.txt").ReadToEnd()
    $two = $text.substring($text.Length-2,2)
    if ($two -eq "`r`n")
    {
    	$newContent = $text.Substring(0, $text.Length-2)
    	$stream = [System.IO.StreamWriter]"output.txt"
    	$stream.write($newContent)
    	$stream.close()
    }
    
    
    

     


    -join("74686979616775313440686F746D61696C2E636F6D"-split"(?<=\G.{2})",21|%{[char][int]"0x$_"})
    http://www.myExchangeWorld.com
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, October 19, 2011 8:27 AM
  • I ran the script-part on c:\input.txt separately,

    this would be input.txt

    "a

    d

     

    "

    well no errors, but it didn't delete the last crlf either, nor the white space after "c"

    Wednesday, October 19, 2011 9:01 AM
  • [IO.File]::WriteAllText("output.txt",[IO.File]::ReadAllText("input.txt") -replace "\s")
    

    Wednesday, October 19, 2011 9:57 AM
  • [IO.File]::WriteAllText("output.txt",[IO.File]::ReadAllText("input.txt") -replace "\s")
    

    original a.txt:

    "1

    2

    3"

    $file = Get-ChildItem "c:\a.txt"
    [System.IO.File]::AppendAllText("$file", '±', [System.Text.Encoding]::Unicode)
    foreach ($str in $file) 
    {
    $content = Get-Content -path $str
    $content | foreach {$_ -replace "±",""} | where {$_} | Set-Content $str
    }
    [IO.File]::WriteAllText("$file",[IO.File]::ReadAllText("$file") -replace "\s")

     

    outcome a.txt:

    "123 "

    Wednesday, October 19, 2011 10:48 AM
  • Something didn't paste right.  That should have been:

    $newcontent = ($text = [System.IO.File]::OpenText($file).ReadToEnd()).trim("`n`r")


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Wednesday, October 19, 2011 10:57 AM
  • Something didn't paste right.  That should have been:

    $newcontent = ($text = [System.IO.File]::OpenText($file).ReadToEnd()).trim("`n`r")


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Ok, I included your part in a single script
     
    $file = Get-ChildItem "c:\a.txt"
    [System.IO.File]::AppendAllText("$file", '±', [System.Text.Encoding]::Unicode)
    foreach ($str in $file) 
    {
    $content = Get-Content -path $str
    $content | foreach {$_ -replace "±",""} | where {$_} | Set-Content $str
    }
    $newcontent = ($text = [System.IO.File]::OpenText($file).ReadToEnd()).trim("`n`r")
    $stream = [System.IO.StreamWriter]$file
    $stream.write($newContent)
    $stream.close()
    
    Still getting exceptions starting with StreamWriter
    Cannot convert the "C:\a.txt" value of type "System.IO.FileInfo" to type "System.IO.StreamWriter".
    At D:\PSscripts\t.ps1:9 char:40
    + $stream = [System.IO.StreamWriter]$file <<<<
        + CategoryInfo          : NotSpecified: (:) [], RuntimeException
        + FullyQualifiedErrorId : RuntimeException
    You cannot call a method on a null-valued expression.
    At D:\PSscripts\t.ps1:10 char:14
    + $stream.write <<<< ($newContent)
        + CategoryInfo          : InvalidOperation: (write:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull
    You cannot call a method on a null-valued expression.
    At D:\PSscripts\t.ps1:11 char:14
    + $stream.close <<<< ()
        + CategoryInfo          : InvalidOperation: (close:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull
    p.s.
    The intriguing part is that after trimming in $newcontent, in powershell console, the test is visibly ok, however in the text file, can still be seen.
    le. as I've noticed, the original $file, in PS console is visibly ok (without white-space and end-crlf)


    • Edited by Dmmnn Wednesday, October 19, 2011 1:12 PM
    Wednesday, October 19, 2011 12:24 PM
  •  

    It's expecting a string argument, not a fileinfo object.  Try changing $file to just a string.

    $file = "c:\a.txt"


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Wednesday, October 19, 2011 1:14 PM
  • tried this with different files, same error.
    Cannot convert value "c:\a.txt" to type "System.IO.StreamWriter". Error: "The process cannot access the file
    'c:\a.txt' because it is being used by another process."
    At D:\PSscripts\t.ps1:9 char:35
    + $stream = [System.IO.StreamWriter] <<<< "c:\a.txt"
        + CategoryInfo          : NotSpecified: (:) [], RuntimeException
        + FullyQualifiedErrorId : RuntimeException
    You cannot call a method on a null-valued expression.
    At D:\PSscripts\t.ps1:10 char:14
    + $stream.write <<<< ($newContent)
        + CategoryInfo          : InvalidOperation: (write:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull
    You cannot call a method on a null-valued expression.
    At D:\PSscripts\t.ps1:11 char:14
    + $stream.close <<<< ()
        + CategoryInfo          : InvalidOperation: (close:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull
    Moreover, if it would work, I would lose the assignment values that $files could take from an array or lookup, as in the initial sequence, there is a variable $element, which takes all sort of values from an array.
    the initial sequence:
    # $loc = \\ka2, ..., \\ka101
    # $apname = smsytlicktyanfl, %suffix% @end/trial/done
    clear-Host
    #$file = Get-ChildItem "c:\a.txt"
    $locfile = "\\ka2\igs\App\fig\smsytlicktyanel.es\app.config", "\\ka2\igs\App\fig\smsytlicktyanfl.ed\app.config", "\\ka2\igs\App\fig\smsytlicktyanrl.ee\app.config"
    $ol = New-Object -comObject Outlook.Application 
    $mail = $ol.CreateItem(0) 
    $Mail.Recipients.Add("testmail@testserver.com")
    $Mail.Subject = "PS1 Run-test" 
    foreach ($element in $locfile)
    {
    $s=$s + $element.substring(18,18) + "`n"
    }
    $Mail.Body = "testing this with split" + "`n" + $s
    $Mail.Send()
    foreach ($element in $locfile) 
    {
    [System.IO.File]::AppendAllText("$element", '&', [System.Text.Encoding]::Unicode)
    foreach ($str in $element) 
    {
    $content = Get-Content -path $str
    $content | foreach {$_ -replace "&",""} | Set-Content $str
    }
    }
    echo "Done`n"
    $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    exit
    



    • Edited by Dmmnn Wednesday, October 19, 2011 3:18 PM
    Wednesday, October 19, 2011 3:17 PM
  •  
    This works for me:
    $file = "c:\testfiles\test.txt"
    $in = [System.IO.File]::OpenText($file)
    $text = ($in.readtoend()).trim("`r`n")
    $in.close()
    
    $stream = [System.IO.StreamWriter]$file
    $stream.write($text)
    $stream.close()
    
    You need to provide it wth string arguments, so if you're doing a directory lookup, you want the fullname property of the filleinfo object as the argument.

    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    • Edited by mjolinor Wednesday, October 19, 2011 3:47 PM
    • Marked as answer by Dmmnn Wednesday, October 19, 2011 8:40 PM
    Wednesday, October 19, 2011 3:46 PM
  • I found that New-Item don't add anything at the end so you could overwrite the file with it. For example here I create a file that end with "-" and then i remove it and finally i overwrite it.
    New-Item -ItemType file -Value "lala`r`nEnd.-" -Path texto.txt -for
    (${c:texto.txt} -replace "-","" ) -join "`r`n"|% { ni -itemtype file -Path texto.txt -Value $_ -for}
    
    


    You don't have the necessity to remove a last blank line because it doesn't going to exist.  Alternativelly you could use the ReadAllText method instead of the array concat(I think that this is more efficient):

     

    # Create file
    ni -it file -val "Uno`r`nDos`r`nEnd." -p texto.txt -for 
    # Append content
    [IO.File]::AppendAllText($pwd.path+"\texto.txt", "-") 
    # Remove the appended content
    ni -it file -path texto.txt -val ([regex]::replace([IO.File]::ReadAllText($pwd.path+"\texto.txt"), "-$","")) -Force 
    

    • Edited by voodoomsr Wednesday, October 19, 2011 8:00 PM second example
    • Marked as answer by Dmmnn Wednesday, October 19, 2011 8:40 PM
    Wednesday, October 19, 2011 4:53 PM
  • thanks to all for the help! especially mjolinor voodoomsr

    yes, last two methods worked as charm!


    • Edited by Dmmnn Wednesday, October 19, 2011 9:06 PM
    Wednesday, October 19, 2011 8:45 PM
  • In Powershell:

    gc FileWithEmptyLines.txt | where {$_ -ne ""} > FileWithNoEmptyLines.txt


    • Edited by Stuart Dobson Wednesday, July 25, 2012 4:56 AM
    • Proposed as answer by Niral Mistry Monday, November 11, 2013 9:50 AM
    Wednesday, July 25, 2012 4:55 AM