Isso também pode ser feito com os cmdlets internos, mas eu ficaria desconfiado de executar Get-Content
em todos os arquivos com mais de 100 MB. Se você quiser tentar, talvez queira um equivalente para tail
. Eu não tenho certeza se eles são espertos o suficiente para pular para frente, ou se eles tentam ler todas as linhas desde o início e só exibem as últimas X linhas. Obviamente, a última abordagem demoraria um pouco se estivesse tentando ler e pular 90 GB.
Se você não se importa com as ferramentas incorporadas ao Windows, acredito que a implementação do% GNUtail
seja mais inteligente. Isso pode ser executado no WSL ou em uma das muitas portas.
Mantendo o script PowerShell / .NET puro, adaptarei um script do PowerShell anterior projetado para dividir um único grande Arquivo. Este script foi escrito para usar blocos de 4 kB, minimizando o uso da memória. Podemos primeiro procurar para a localização correta (uma operação quase instantânea) e copiar a partir daí. Por simplicidade, nenhuma análise para a próxima / anterior linha quebra é feita; estamos simplesmente pulando para um byte específico (até mesmo para o meio da linha).
Se preferir procurar uma certa distância desde o começo, você pode, por exemplo, substitua $seekLoc = 97GB
e $seekOrigin = "Begin"
e talvez $copyLen = 10GB
seja seguro e não perca o final.
$inFile = "foo.txt"
$outFile = "bar.txt"
$seekLoc = -1GB
$seekOrigin = "End"
$copyLen = 1GB
# need to sync .NET CurrentDirectory with PowerShell CurrentDirectory
# https://stackoverflow.com/questions/18862716/current-directory-from-a-dll-invoked-from-powershell-wrong
[Environment]::CurrentDirectory = Get-Location
# 4k is a fairly typical and 'safe' chunk size
# partial chunks are handled below
$bytes = New-Object byte[] 4096
$inReader = [System.IO.File]::OpenRead($inFile)
$inReader.Seek($seekLoc, $seekOrigin)
# better to use functions but a flag is easier in a simple script
$finished = $false
$bytesToRead = $copyLen
# Just like File::OpenWrite except CreateNew instead to prevent overwriting existing files
$outWriter = New-Object System.IO.FileStream "$outFile",CreateNew,Write,None
while ($bytesToRead) {
# read up to 4k at a time, but no more than the remaining bytes from copyLen
$bytesRead = $inReader.Read($bytes, 0, [Math]::Min($bytes.Length, $bytesToRead))
# 0 bytes read means we've reached the end of the input file
if (!$bytesRead) {
break
}
$bytesToRead -= $bytesRead
$outWriter.Write($bytes, 0, $bytesRead)
}
# dispose closes the stream and releases locks
$outWriter.Dispose()
$inReader.Dispose()