Windows Powershell - 逐行删除

ada*_*m78 0 powershell file

我有一个大的csv文件(1.6gb).如何删除特定行,例如1005行?

mkl*_*nt0 6

注意:以下解决方案按行号从任何基于文本的文件中删除单行.正如marsze指出的那样,其他注意事项可能适用于CSV文件,其中必须注意不要消除标题行,如果行具有嵌入换行符的值,则行可以跨越多行; 在这种情况下,使用CSV解析器是更好的选择.

如果性能不是最重要的,这里有一个基于管道内存管理方式:

Get-Content file.txt | 
  Where-Object ReadCount -ne 1005 |
    Set-Content -Encoding Utf8 new-file.txt
Run Code Online (Sandbox Code Playgroud)

Get-Content.ReadCount它输出的每一行添加一个(有点模糊命名的)属性,其中包含1基于行的行号.

  • 请注意,输入文件的字符编码不会被保留Get-Content,因此您应该Set-Content使用UTF-8作为示例显式控制'st输出编码,如上所示.

  • 如果不将整个文件作为一个整体读入内存,则必须至少暂时输出到文件; 您可以使用临时输出文件替换原始文件
    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)]
Run Code Online (Sandbox Code Playgroud)
  • 注意需要使用"$PWD/$file",即显式地将当前目录路径前置到存储在其中的相对路径$file,因为.NET框架对当前目录的概念与PowerShell的不同.

    • 虽然$lines = Get-Content $file在功能上等同于$lines = [IO.File]::ReadAllLines("$PWD/$file")它,但它的表现会明显变差.
  • 0..1003创建从索引数组01003; 通过输入数组的其余部分+将该数组与索引连接起来1005; 请注意,数组索引是0基于的,而行号是1基于的.

  • 还注意到得到的阵列是如何传递到Set-Content作为直接参数通过-Value,这是比经由管线(通过它更快... | Set-Content ...),其中,将执行元件逐元素的处理.


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

$file = 'file.txt'
$outFile = [IO.File]::CreateText("$PWD/new-file.txt")
$lineNo = 0
try {
  foreach ($line in [IO.File]::ReadLines("$PWD/$file")) {
    if (++$lineNo -eq 1005) { continue }
    $outFile.WriteLine($line)
  }
} finally {
  $outFile.Dispose()
}
Run Code Online (Sandbox Code Playgroud)

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