Powershell - 如何从一个目录中提取所有文本文件的第一行到单个输出文件中?

10

我有一个包含大约10,000个长度不同的文本文件的目录。所有文件大小都超过1GB。

我需要提取每个文件的第一行,并将其插入到同一目录下的新文本文件中。

我尝试了通常的MS-DOS批处理文件方法,但由于文件太大而崩溃。

是否有一种使用Streamreader在Powershell中完成此操作的方法?


结合使用 Get-ContentOut-File 命令可以实现此目的,请在谷歌上搜索它们。 - Raf
4
感谢您的“有用”的建议。实际上,Get-Content在执行操作之前会将整个文件的内容加载到内存中。我曾经尝试在大文件上使用它,在一个1 GB的文件上,它分配了8GB的RAM,并使用了全部的RAM,然后开始向磁盘换页,大约花费了8个小时才读取出一行内容。这对于需要重复10,000次的工作来说并不理想。“Google一下”并不是我在这里寻求的建议类型。 - Ten98
3个回答

13

编辑:当然,有一种内置的方式:

$firstLine = Get-Content -Path $fileName -TotalCount 1

[Ack Raf's comment]


建议查看File.ReadLines方法:该方法会惰性地读取文件内容,每次迭代返回的枚举器只读取内容。

我不确定Select-Object -first 1是否会在读取一行后主动停止流水线,如果是,则这是获取第一行的最简单方法:

$firstLine = [IO.File]::ReadLines($filename, [text.encoding]::UTF8) | Select-Object -first 1
否则,类似于:
$lines = [IO.File]::ReadLines($filename, [text.encoding]::UTF8); # adjust to correct encoding
$lineEnum = $lines.GetEncumerator();
if ($lineEnum.MoveNext()) {
  $firstLine = $lineEnum.Current;
} else {
  # No lines in file
}

NB. 这假设至少需要 PowerShell V3 来使用 .NET V4。


谢谢!由于我的文件超过1GB,而且“Get-Content”在试图“获取”其内容之前将整个文件加载到内存中,因此我无法使用您的顶部建议。但是您的第三个建议完美地解决了问题! :) - Ten98
1
最佳建议很合适。使用-TotalCount参数针对1GB文件进行测试,并查看它是否能立即返回第一行。 - mjolinor

8
为了只读取一行,你也可以使用以下方法:
$file = new-object System.IO.StreamReader($filename)
$file.ReadLine()
$file.close()

使用OutVariable,您可以在一行代码中编写它:(点击此处了解更多)
$text = (new-object System.IO.StreamReader($filename) -OutVariable $file).ReadLine();$file.Close()

3

简洁明了:

cd c:\path\to\my\text\files\
Get-Content *.txt -First 1 > output.txt

编辑于2018年11月:根据文档,"TotalCount参数限制检索前n行。" 这似乎可以最小化资源使用。请自行测试并添加您的评论。
cd c:\path\to\my\text\files\
Get-Content *.txt -TotalCount 1 > output.txt

这会将整个文件加载到内存中,这在这种情况下不可行/不理想。 - SebK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接