Windows Powershell-按行号删除一行

时间:2019-01-07 12:05:46

标签: powershell file

我的csv文件很大(1.6gb)。如何删除特定的行,例如1005行?

1 个答案:

答案 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创建一个从01003的索引数组; +通过输入数组的其余部分将索引为1005的数组连接起来;请注意,数组索引基于0,而行号基于1

  • 还请注意如何通过Set-Content将结果数组作为直接参数传递给-Value,这比通过管道传递数组快得多({{ 1}}),在其中将执行逐元素处理。


最后,一种比基于管道的方法快的内存友好方法

... | Set-Content ...

与基于管道的命令一样,之后您可能必须用新文件替换原始文件。