且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用Powershell从文件中删除最后一行

更新时间:2023-02-05 10:47:52

如果你已经知道文件的最后一件事是一个CRLF,你想摆脱(你知道编码),你可以走快速路线:

If you already know that the very last thing of the file is a CRLF you want to get rid of (and you know the encoding too) you can go the quick route:

$stream = [IO.File]::OpenWrite('foo.txt')
$stream.SetLength($stream.Length - 2)
$stream.Close()
$stream.Dispose()

这是文件的in-place截断。它工作没有读取所有的文件到内存(非常好,如果你有一个非常大文件)。它适用于ASCII,Latin- *和UTF-8。它不会以这种方式为UTF-16(在这种情况下,你必须从末尾删除四个字节)。

This is an in-place truncation of the file. It works without reading all the file into memory (very nice if you have a very large file). It works for ASCII, Latin-* and UTF-8. It won't work that way for UTF-16 (you'd have to remove four bytes from the end, in that case).

您可以包括一个额外的检查最后两个字节是真正要删除的内容:

You can include an additional check that the last two bytes are really what you want to remove:

$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

Again, adapt if you use another encoding, e.g. for UTF-16 you need to compare to either 0,10,0,13 or 10,0,13,0.

同意,这不是PowerShell-ey,但自从我必须处理一个700-MiB数据库转储我警惕的读取潜在的大文件到内存完全;)

Agreed, this is not very PowerShell-ey, but ever since I had to process a 700-MiB database dump I am wary of reading potentially large files into memory completely ;)