我的csv文件很大(1.6gb)。如何删除特定的行,例如1005行?
答案 0 :(得分:6)
注意:以下解决方案通过行号从任何基于文本的文件中消除了一行。正如marsze所指出的, CSV 文件可能还有其他注意事项,必须注意不要删除标题行,并且如果行中的值带有嵌入的换行符,则行可能跨越多行。在这种情况下,使用CSV解析器是更好的选择。
如果性能不是最重要的,这是一种基于内存的基于管道的方法:
Get-Content file.txt |
Where-Object ReadCount -ne 1005 |
Set-Content -Encoding Utf8 new-file.txt
Get-Content
向其输出的每一行添加一个(名称模糊).ReadCount
属性,该属性包含基于1
的行号。
请注意,Get-Content
不会保留输入文件的字符编码,因此,您应该使用UTF-8作为示例,显式地控制Set-Content
的st输出编码,如上所示。
没有将整个文件作为一个整体读取到内存中,必须至少临时地输出到 new 文件;您可以使用
用临时输出文件替换原始文件
Move-Item -Force new-file.txt file.txt
基于直接使用.NET框架的更快但占用大量内存的替代方法,它还允许您就地更新文件:
$file = 'file.txt'
$lines = [IO.File]::ReadAllLines("$PWD/$file")
Set-Content -Encoding UTF8 $file -Value $lines[0..1003 + 1005..($lines.Count-1)]
请注意需要使用"$PWD/$file"
,即,将当前目录路径显式添加到$file
中存储的相对路径之前,因为.NET框架对当前目录的含义与PowerShell的不同。
$lines = Get-Content $file
在功能上等效于$lines = [IO.File]::ReadAllLines("$PWD/$file")
,但其性能明显较差。 0..1003
创建一个从0
到1003
的索引数组; +
通过输入数组的其余部分将索引为1005
的数组连接起来;请注意,数组索引基于0
,而行号基于1
。
还请注意如何通过Set-Content
将结果数组作为直接参数传递给-Value
,这比通过管道传递数组快得多({{ 1}}),在其中将执行逐元素处理。
最后,一种比基于管道的方法快的内存友好方法:
... | Set-Content ...
与基于管道的命令一样,之后您可能必须用新文件替换原始文件。