Share via


Removing trailing blank lines in PowerShell

Question

Tuesday, October 18, 2011 7:22 AM | 1 vote

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!

All replies (28)

Wednesday, October 19, 2011 3:46 PM ✅Answered | 1 vote

 

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 " "


Wednesday, October 19, 2011 4:53 PM ✅Answered

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 

Tuesday, October 18, 2011 8:44 AM

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 9:15 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:40 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.


Tuesday, October 18, 2011 10:31 AM

it actually adds at the end of the text, one space " " + 1 trailing line break


Tuesday, October 18, 2011 10:51 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.


Tuesday, October 18, 2011 12:19 PM

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 :)


Tuesday, October 18, 2011 1:00 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:43 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 2:27 PM

it didn't work :(

thanks anyway mjolinor.


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.


Tuesday, October 18, 2011 2:47 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


Tuesday, October 18, 2011 2:49 PM

p.s.:

\system32\WindowsPowerShell\v1.0\


Tuesday, October 18, 2011 2:54 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 3:00 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("[email protected]")

$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:40 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 " "


Wednesday, October 19, 2011 7:46 AM

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 8:27 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 9:01 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:57 AM

[IO.File]::WriteAllText("output.txt",[IO.File]::ReadAllText("input.txt") -replace "\s")

Wednesday, October 19, 2011 10:48 AM

[IO.File]::WriteAllText("output.txt",[IO.File]::ReadAllText("input.txt") -replace "\s")
original a.txt:"123"

$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: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 " "


Wednesday, October 19, 2011 12:24 PM

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)


Wednesday, October 19, 2011 1:14 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 3:17 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("[email protected]")
$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

Wednesday, October 19, 2011 8:45 PM

thanks to all for the help! especially mjolinorvoodoomsr

yes, last two methods worked as charm!


Wednesday, July 25, 2012 4:55 AM | 1 vote

In Powershell:

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