我正在使用
gc FileWithEmptyLines.txt | where {$_ -ne ""} > FileWithNoEmptyLines.txt
删除SSRS放在CSV底部的空行。
但是,包含数据的最后一行以CRLF结尾(在Notepad ++中查看) - 并且不会删除,因此从技术上讲,文件底部仍然有一个空行。
有没有办法从最后一行删除此CRLF(并保持数据完好无损)?
答案 0 :(得分:13)
如果您已经知道该文件的最后一件事是CRLF,您想要摆脱(并且您也知道编码),您可以快速路线:
$stream = [IO.File]::OpenWrite('foo.txt')
$stream.SetLength($stream.Length - 2)
$stream.Close()
$stream.Dispose()
这是文件的就地截断。它可以在不将所有文件读入内存的情况下工作(非常好,如果你有一个非常大文件)。它适用于ASCII,Latin- *和UTF-8。对于UTF-16,它将无法正常工作(在这种情况下,您必须从末尾删除四个字节)。
您可以添加一项额外的检查,确认最后两个字节是 您要删除的内容:
$stream = [IO.File]::Open('foo.txt', [IO.FileMode]::Open)
$stream.Position = $stream.Length - 2
$bytes = 0..1 | %{ $stream.ReadByte() }
$compareBytes = 13,10 # CR,LF
if ("$bytes" -eq "$compareBytes") {
$stream.SetLength($stream.Length - 2)
}
$stream.Close()
$stream.Dispose()
同样,如果您使用其他编码,请进行调整,例如:对于UTF-16,您需要与0,10,0,13
或10,0,13,0
进行比较。
同意,这不是PowerShell-ey,但是自从我不得不处理700-MiB数据库转储以来,我对将可能存在的大文件完全读入内存持谨慎态度;)
答案 1 :(得分:6)
使用Get-Content
读取文件时,它会将每一行作为字符串流入管道。当Out-File
(基本上是>
是别名)获取这些字符串时,它总是附加行终止符序列。如果文件不是太大,请尝试以下操作:
$text = [IO.File]::ReadAllText("c:\FileWithEmptyLinesAtEnd.txt")
[IO.File]::WriteAllText("c:\FileWithEmptyLinesAtEnd.txt", $text.TrimEnd())
这是之前的文件:
14> fhex .\FileWithEmptyLinesAtEnd.txt
Address: 0 1 2 3 4 5 6 7 8 9 A B C D E F ASCII
-------- ----------------------------------------------- ----------------
00000000 73 65 72 76 65 72 31 2C 73 65 72 76 65 72 32 2E server1,server2.
00000010 64 6F 6D 61 69 6E 2E 6C 6F 63 61 6C 2C 73 65 72 domain.local,ser
00000020 76 65 72 33 0D 0A 20 20 20 20 20 20 ver3..
之后:
19> fhex .\FileWithEmptyLinesAtEnd.txt
Address: 0 1 2 3 4 5 6 7 8 9 A B C D E F ASCII
-------- ----------------------------------------------- ----------------
00000000 73 65 72 76 65 72 31 2C 73 65 72 76 65 72 32 2E server1,server2.
00000010 64 6F 6D 61 69 6E 2E 6C 6F 63 61 6C 2C 73 65 72 domain.local,ser
00000020 76 65 72 33 ver3
答案 2 :(得分:2)
我不确定这种情况有多适用,但我谷歌搜索删除文本文件的最后一行导致我在这里,上面的示例/解决方案不起作用。这是我能够使用它来执行此操作的命令:
$file = "file.txt"
Get-Content $file | Measure-Object -Line
$a = (Get-Content $file | Measure-Object)
(Get-Content $file) | ? {($a.count-1)-notcontains $_.ReadCount} | Set-Content $file
如果您正在使用大文件,则可能需要先将其传输到临时文件。
答案 3 :(得分:0)
试试这个,虽然它会删除文件中的所有空行
(Get-Content c:\FileWithEmptyLinesAtEnd.txt) |
Where-Object {$_ -match '\S'} |
Out-File c:\FileWithEmptyLinesAtEnd.txt
答案 4 :(得分:0)
对于'UCS-2 Little Endian'文件格式,请使用:
$stream = [IO.File]::Open($filename, [IO.FileMode]::Open)
$stream.Position = $stream.Length - 4
$bytes = 0..3 | %{ $stream.ReadByte() }
$compareBytes = 13,0,10,0 # CR,LF
echo "bytes: "$bytes
if ("$bytes" -eq "$compareBytes")
{
$stream.SetLength($stream.Length - 4)
}
$stream.Close()
$stream.Dispose()