Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Windows中获取大型文件的最后n行或字节(如Unix的尾部)。避免耗时的选择_Windows_Powershell_Batch File_Tail - Fatal编程技术网

在Windows中获取大型文件的最后n行或字节(如Unix的尾部)。避免耗时的选择

在Windows中获取大型文件的最后n行或字节(如Unix的尾部)。避免耗时的选择,windows,powershell,batch-file,tail,Windows,Powershell,Batch File,Tail,我需要在Windows7中检索最后n行1-4GB的大型文件。 由于公司限制,我无法运行任何非内置命令。 问题是,我找到的所有解决方案似乎都读取整个文件,因此速度非常慢 这能很快完成吗 注: 我很快就拿到了前n行。 如果我得到最后的n个字节就可以了。我将其用于前n个字节。 这里的解决方案不起作用。 使用-wait并不能加快速度。我没有尾巴,我不知道它是否能很快工作 附:关于头部和尾部,有很多相关的问题,但没有集中在速度问题上。因此,有用的或公认的答案在这里可能没有用处。例如: 如果您有PowerS

我需要在Windows7中检索最后n行1-4GB的大型文件。 由于公司限制,我无法运行任何非内置命令。 问题是,我找到的所有解决方案似乎都读取整个文件,因此速度非常慢

这能很快完成吗

注:

我很快就拿到了前n行。 如果我得到最后的n个字节就可以了。我将其用于前n个字节。 这里的解决方案不起作用。 使用-wait并不能加快速度。我没有尾巴,我不知道它是否能很快工作

附:关于头部和尾部,有很多相关的问题,但没有集中在速度问题上。因此,有用的或公认的答案在这里可能没有用处。例如:


如果您有PowerShell 3或更高版本,则可以使用-Tail参数获取内容以获取最后n行


在本地SSD上的一个34MB文本文件上,它在1毫秒内返回,而获取内容的时间为8.5秒|选择-最后5个

如何读取演示的最后8个字节:

$fpath = "C:\10GBfile.dat"
$fs = [IO.File]::OpenRead($fpath)
$fs.Seek(-8, 'End') | Out-Null
for ($i = 0; $i -lt 8; $i++)
{
    $fs.ReadByte()
}
更新。要将字节解释为字符串,但请确保选择正确的编码-此处使用UTF8:

$N = 8
$fpath = "C:\10GBfile.dat"
$fs = [IO.File]::OpenRead($fpath)
$fs.Seek(-$N, [System.IO.SeekOrigin]::End) | Out-Null
$buffer = new-object Byte[] $N
$fs.Read($buffer, 0, $N) | Out-Null
$fs.Close()
[System.Text.Encoding]::UTF8.GetString($buffer)
更新2。要读取最后M行,我们将按部分读取文件,直到结果中有超过M个换行字符序列:

$M = 3
$fpath = "C:\10GBfile.dat"

$result = ""
$seq = "`r`n"
$buffer_size = 10
$buffer = new-object Byte[] $buffer_size

$fs = [IO.File]::OpenRead($fpath)
while (([regex]::Matches($result, $seq)).Count -lt $M)
{
    $fs.Seek(-($result.Length + $buffer_size), [System.IO.SeekOrigin]::End) | Out-Null
    $fs.Read($buffer, 0, $buffer_size) | Out-Null
    $result = [System.Text.Encoding]::UTF8.GetString($buffer) + $result
}
$fs.Close()

($result -split $seq) | Select -Last $M
尝试使用更大的$buffer_大小-理想情况下,这等于预期的平均行长度,以减少磁盘操作。还要注意$seq-这可能是\r\n或只是\r\n。 这是一段非常脏的代码,没有任何错误处理和优化。

With,它解决了速度问题,通过谷歌搜索,我最终使用了这个脚本

$fpath = $Args[1]
$fs = [IO.File]::OpenRead($fpath)
$fs.Seek(-$Args[0], 'End') | Out-Null
$mystr = ''
for ($i = 0; $i -lt $Args[0]; $i++)
{
    $mystr = ($mystr) + ([char[]]($fs.ReadByte()))
}
$fs.Close()
Write-Host $mystr
我从包含

@PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '.\myscript.ps1' %1 %2"

感谢。

这不是一个答案,而是对sancho.s答案的一个大评论

当您希望使用批处理文件中的小型PowerShell脚本时,我建议您使用以下方法,该方法更简单,并允许将所有代码保留在同一批处理文件中:

@PowerShell  ^
   $fpath = %2;  ^
   $fs = [IO.File]::OpenRead($fpath);  ^
   $fs.Seek(-%1, 'End') ^| Out-Null;  ^
   $mystr = '';  ^
   for ($i = 0; $i -lt %1; $i++)  ^
   {  ^
      $mystr = ($mystr) + ([char[]]($fs.ReadByte()));  ^
   }  ^
   Write-Host $mystr
%End PowerShell%

当文件已经打开时,最好使用

Get-Content $fpath -tail 10

由于使用1个参数调用OpenRead时出现异常:进程无法访问文件…

批处理文件是一个不好的选择,因为正确处理二进制文件非常困难,甚至几乎不可能,我想您所说的是,您希望提取一定数量的字节,而不是字符或行;所以我肯定会选择PS…我没有-Tail。然后将您的环境升级到最新版本的PowerShell。除非您有一些奇怪的兼容性问题需要保留,否则没有理由不升级到至少v3,最好是4或5,无论您的系统支持的最高版本是什么。由于相同的公司限制,我无法运行任何非内置命令,我也无法升级。我得到了他们给我的东西。对不起,如果一个被认为是windows核心组件的软件在发布后的三年多里没有考虑升级,我认为环境已经坏了。还有什么是过时的,甚至更糟糕的,没有打补丁的安全和错误修复?当你背负着过时的软件时,你能将自己的职业和技术知识真正提升到什么程度?这就是为什么你要继续前进——因为在这样的环境中你无法提高自己的技能。我不是在软件公司工作。没有PS3并不是需要去别的地方的症状,即使有它会很方便!。这是我的看法。谢谢你的生动!这实际上工作得很快,但它输出每个字节的十进制代码。我的意思是获取相应的字符字符串。已更新,请检查。刚刚注意到我在第一个示例中忘记了$fs.Close,但我希望它对于这个概念验证代码没有那么重要。祝你好运谢谢我正在写我自己的代码,并且发布了一个同样有效的答案。我通常不编码PS,所以它可能是基本的。字节到字符总是依赖于编码,不要忘记it@AzizKabyshev-没错。对于我知道我将拥有的文件,这是可以的。这对我非常有用。注意:执行此操作的方法是使用myscript.bat nbytes“myfile”。必须使用带单引号的文件名。与执行调用ps1脚本的批处理文件不同,无引号或双引号不起作用。
Get-Content $fpath -tail 10