注意:下面的解决方案从任何基于文本的文件中逐行删除一行。AS
marsze
指出,其他考虑可能适用于
猪瘟病毒
文件,必须注意不要删除标题行,如果行具有内嵌换行符的值,则行可以跨多行;在这种情况下,使用csv解析器是更好的选择。
如果性能不是最重要的,这里是
基于内存友好管道的方法
做到这一点:
Get-Content file.txt |
Where-Object ReadCount -ne 1005 |
Set-Content -Encoding Utf8 new-file.txt
Get-Content
添加(名称有点模糊)
.ReadCount
属性设置为它输出的每一行,其中包含
1
-基于行号。
-
请注意,输入文件的字符编码不是由
获取内容
,所以你应该控制
Set-Content
'ST输出显式编码,如上图所示,以utf-8为例。
-
如果不将整个文件作为一个整体读取到内存中,则必须输出到
新的
文件,至少是临时的;可以用临时输出文件替换原始文件
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
通过输入数组的其余部分;请注意,数组索引是
零
-基于,而行号是
一
基础。
-
还要注意结果数组是如何传递给
设置内容
作为一个
直接论证
通过
-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()
}
与基于管道的命令一样,以后可能必须用新文件替换原始文件。