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

wfveoks0  于 5个月前  发布在  Shell
关注(0)|答案(5)|浏览(91)

我正在使用

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

字符串
来删除SSRS放在CSV底部的空行。
但是,最后一行(上面有数据)以CRLF结尾(在Notepad++中可以看到),而且这一行没有被删除,因此从技术上讲,文件底部仍然有一个空行。
有没有办法从最后一行中删除这个CRLF(当然,还要保持数据完整)?

e4eetjau

e4eetjau1#

如果你已经知道文件的最后一件事是你想摆脱的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,1310,0,13,0进行比较。
同意,这不是很PowerShell-ey,但自从我不得不处理700-MiB数据库转储后,我就对将潜在的大文件完全阅读到内存中持谨慎态度;)

u91tlkcl

u91tlkcl2#

当你使用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

a11xaf1n

a11xaf1n3#

我不知道这是否适用于这种情况,但我的谷歌搜索删除文本文件的最后一行导致我在这里,上面的例子/解决方案不起作用。这是我能够使用的命令来实现这一点:

$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

字符串
如果你正在处理一个大文件,你可能想先把它通过管道传输到一个临时文件。

klsxnrf1

klsxnrf14#

对于“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()

字符串

z31licg0

z31licg05#

试试这个方法,尽管它会从你的文件中删除所有的空行

(Get-Content c:\FileWithEmptyLinesAtEnd.txt) | 
Where-Object {$_ -match '\S'} | 
Out-File c:\FileWithEmptyLinesAtEnd.txt

字符串

相关问题