2009-06-16 3 views
47

Мне нужно разделить большой (500   МБ) текстовый файл (файл исключения log4net) на управляемые фрагменты, такие как 100 5   МБ файлов.Как разбить текстовый файл с помощью PowerShell?

Я бы подумал, что это должна быть прогулка в парке для PowerShell. Как мне это сделать?

ответ

34

Это довольно простая задача для PowerShell, осложненная тем, что стандартный командлет Get-Content слишком плохо обрабатывает очень большие файлы. То, что я хотел бы предложить, это использовать .NET StreamReader class, чтобы прочитать файл в строке в сценарии PowerShell и использовать командлет Add-Content для записи каждой строки в файл с постоянно увеличивающимся индексом в имени файла. Что-то вроде этого:

$upperBound = 50MB # calculated by Powershell 
$ext = "log" 
$rootName = "log_" 

$reader = new-object System.IO.StreamReader("C:\Exceptions.log") 
$count = 1 
$fileName = "{0}{1}.{2}" -f ($rootName, $count, $ext) 
while(($line = $reader.ReadLine()) -ne $null) 
{ 
    Add-Content -path $fileName -value $line 
    if((Get-ChildItem -path $fileName).Length -ge $upperBound) 
    { 
     ++$count 
     $fileName = "{0}{1}.{2}" -f ($rootName, $count, $ext) 
    } 
} 

$reader.Close() 
+1

Это именно то, что я искал, и спасибо за подтверждение моей догадки, что получение контента не очень велико с большими файлами. –

+3

Полезный совет: вы можете выразить числа вроде этого ... $ upperBound = 5MB – Lee

+3

Для тех, кто слишком ленив, чтобы прочитать следующий ответ, вы можете установить объект $ reader через $ reader = new-object System.IO.StreamReader ($ inputFile) – lmsurprenant

15

Мне часто нужно делать то же самое. Трюк получает заголовок, повторяемый в каждом из разделенных кусков. Я написал следующий командлет (PowerShell v2 CTP 3), и он делает трюк.

############################################################################## 
#.SYNOPSIS 
# Breaks a text file into multiple text files in a destination, where each 
# file contains a maximum number of lines. 
# 
#.DESCRIPTION 
# When working with files that have a header, it is often desirable to have 
# the header information repeated in all of the split files. Split-File 
# supports this functionality with the -rc (RepeatCount) parameter. 
# 
#.PARAMETER Path 
# Specifies the path to an item. Wildcards are permitted. 
# 
#.PARAMETER LiteralPath 
# Specifies the path to an item. Unlike Path, the value of LiteralPath is 
# used exactly as it is typed. No characters are interpreted as wildcards. 
# If the path includes escape characters, enclose it in single quotation marks. 
# Single quotation marks tell Windows PowerShell not to interpret any 
# characters as escape sequences. 
# 
#.PARAMETER Destination 
# (Or -d) The location in which to place the chunked output files. 
# 
#.PARAMETER Count 
# (Or -c) The maximum number of lines in each file. 
# 
#.PARAMETER RepeatCount 
# (Or -rc) Specifies the number of "header" lines from the input file that will 
# be repeated in each output file. Typically this is 0 or 1 but it can be any 
# number of lines. 
# 
#.EXAMPLE 
# Split-File bigfile.csv 3000 -rc 1 
# 
#.LINK 
# Out-TempFile 
############################################################################## 
function Split-File { 

    [CmdletBinding(DefaultParameterSetName='Path')] 
    param(

     [Parameter(ParameterSetName='Path', Position=1, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 
     [String[]]$Path, 

     [Alias("PSPath")] 
     [Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)] 
     [String[]]$LiteralPath, 

     [Alias('c')] 
     [Parameter(Position=2,Mandatory=$true)] 
     [Int32]$Count, 

     [Alias('d')] 
     [Parameter(Position=3)] 
     [String]$Destination='.', 

     [Alias('rc')] 
     [Parameter()] 
     [Int32]$RepeatCount 

    ) 

    process { 

     # yeah! the cmdlet supports wildcards 
     if ($LiteralPath) { $ResolveArgs = @{LiteralPath=$LiteralPath} } 
     elseif ($Path) { $ResolveArgs = @{Path=$Path} } 

     Resolve-Path @ResolveArgs | %{ 

      $InputName = [IO.Path]::GetFileNameWithoutExtension($_) 
      $InputExt = [IO.Path]::GetExtension($_) 

      if ($RepeatCount) { $Header = Get-Content $_ -TotalCount:$RepeatCount } 

      # get the input file in manageable chunks 

      $Part = 1 
      Get-Content $_ -ReadCount:$Count | %{ 

       # make an output filename with a suffix 
       $OutputFile = Join-Path $Destination ('{0}-{1:0000}{2}' -f ($InputName,$Part,$InputExt)) 

       # In the first iteration the header will be 
       # copied to the output file as usual 
       # on subsequent iterations we have to do it 
       if ($RepeatCount -and $Part -gt 1) { 
        Set-Content $OutputFile $Header 
       } 

       # write this chunk to the output file 
       Write-Host "Writing $OutputFile" 
       Add-Content $OutputFile $_ 

       $Part += 1 

      } 

     } 

    } 

} 
+0

работает красиво. Возможно, вы захотите увеличить количество строк в одном файле. Кроме того, у этого скрипта заканчивается память, если вы пишете огромные файлы. – Wouter

+0

+1 для поддержки заголовков, мой прецедент был CSV тоже. – Kasaku

+0

Очень удобно для разбиения простого текстового файла с одним столбцом имен серверов на кратность для пакетной обработки. – Signal15

2

Я сделал небольшую модификацию для разделения файлов на основе размера каждой части.

############################################################################## 
#.SYNOPSIS 
# Breaks a text file into multiple text files in a destination, where each 
# file contains a maximum number of lines. 
# 
#.DESCRIPTION 
# When working with files that have a header, it is often desirable to have 
# the header information repeated in all of the split files. Split-File 
# supports this functionality with the -rc (RepeatCount) parameter. 
# 
#.PARAMETER Path 
# Specifies the path to an item. Wildcards are permitted. 
# 
#.PARAMETER LiteralPath 
# Specifies the path to an item. Unlike Path, the value of LiteralPath is 
# used exactly as it is typed. No characters are interpreted as wildcards. 
# If the path includes escape characters, enclose it in single quotation marks. 
# Single quotation marks tell Windows PowerShell not to interpret any 
# characters as escape sequences. 
# 
#.PARAMETER Destination 
# (Or -d) The location in which to place the chunked output files. 
# 
#.PARAMETER Size 
# (Or -s) The maximum size of each file. Size must be expressed in MB. 
# 
#.PARAMETER RepeatCount 
# (Or -rc) Specifies the number of "header" lines from the input file that will 
# be repeated in each output file. Typically this is 0 or 1 but it can be any 
# number of lines. 
# 
#.EXAMPLE 
# Split-File bigfile.csv -s 20 -rc 1 
# 
#.LINK 
# Out-TempFile 
############################################################################## 
function Split-File { 

    [CmdletBinding(DefaultParameterSetName='Path')] 
    param(

     [Parameter(ParameterSetName='Path', Position=1, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 
     [String[]]$Path, 

     [Alias("PSPath")] 
     [Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)] 
     [String[]]$LiteralPath, 

     [Alias('s')] 
     [Parameter(Position=2,Mandatory=$true)] 
     [Int32]$Size, 

     [Alias('d')] 
     [Parameter(Position=3)] 
     [String]$Destination='.', 

     [Alias('rc')] 
     [Parameter()] 
     [Int32]$RepeatCount 

    ) 

    process { 

    # yeah! the cmdlet supports wildcards 
     if ($LiteralPath) { $ResolveArgs = @{LiteralPath=$LiteralPath} } 
     elseif ($Path) { $ResolveArgs = @{Path=$Path} } 

     Resolve-Path @ResolveArgs | %{ 

      $InputName = [IO.Path]::GetFileNameWithoutExtension($_) 
      $InputExt = [IO.Path]::GetExtension($_) 

      if ($RepeatCount) { $Header = Get-Content $_ -TotalCount:$RepeatCount } 

    Resolve-Path @ResolveArgs | %{ 

    $InputName = [IO.Path]::GetFileNameWithoutExtension($_) 
    $InputExt = [IO.Path]::GetExtension($_) 

    if ($RepeatCount) { $Header = Get-Content $_ -TotalCount:$RepeatCount } 

    # get the input file in manageable chunks 

    $Part = 1 
    $buffer = "" 
    Get-Content $_ -ReadCount:1 | %{ 

    # make an output filename with a suffix 
    $OutputFile = Join-Path $Destination ('{0}-{1:0000}{2}' -f ($InputName,$Part,$InputExt)) 

    # In the first iteration the header will be 
    # copied to the output file as usual 
    # on subsequent iterations we have to do it 
    if ($RepeatCount -and $Part -gt 1) { 
     Set-Content $OutputFile $Header 
    } 

    # test buffer size and dump data only if buffer is greater than size 
    if ($buffer.length -gt ($Size * 1MB)) { 
     # write this chunk to the output file 
     Write-Host "Writing $OutputFile" 
     Add-Content $OutputFile $buffer 
     $Part += 1 
     $buffer = "" 
    } else { 
     $buffer += $_ + "`r" 
    } 
    } 
    } 
     } 
    } 
} 
14

Я нашел этот вопрос, пытаясь разделить несколько контактов в одном файле VCF vCard для разделения файлов. Вот что я сделал на основе кода Ли. Мне нужно было посмотреть, как создать новый объект StreamReader и изменить значение null до $ null.

$reader = new-object System.IO.StreamReader("C:\Contacts.vcf") 
$count = 1 
$filename = "C:\Contacts\{0}.vcf" -f ($count) 

while(($line = $reader.ReadLine()) -ne $null) 
{ 
    Add-Content -path $fileName -value $line 

    if($line -eq "END:VCARD") 
    { 
     ++$count 
     $filename = "C:\Contacts\{0}.vcf" -f ($count) 
    } 
} 

$reader.Close() 
38

Слово предупреждения относительно некоторых из существующих ответов - они будут работать очень медленно для очень больших файлов. За 1,6   ГБ файл журнала я сдался через пару часов, понимая, что это не закончится, прежде чем я вернусь на работу на следующий день.

Два вопроса: открывается вызов Add-Content, ищет и затем закрывает текущий файл назначения для каждой строки исходного файла. Каждый раз чтение немного исходного файла и поиск новых строк также замедляет работу, но я предполагаю, что основной причиной является Add-Content.

Следующий вариант производит чуть менее приятный вывод: он будет разбивать файлы на середине линии, но он разбивает мой журнал 1,6   ГБ менее чем за минуту:

$from = "C:\temp\large_log.txt" 
$rootName = "C:\temp\large_log_chunk" 
$ext = "txt" 
$upperBound = 100MB 


$fromFile = [io.file]::OpenRead($from) 
$buff = new-object byte[] $upperBound 
$count = $idx = 0 
try { 
    do { 
     "Reading $upperBound" 
     $count = $fromFile.Read($buff, 0, $buff.Length) 
     if ($count -gt 0) { 
      $to = "{0}.{1}.{2}" -f ($rootName, $idx, $ext) 
      $toFile = [io.file]::OpenWrite($to) 
      try { 
       "Writing $count to $to" 
       $tofile.Write($buff, 0, $count) 
      } finally { 
       $tofile.Close() 
      } 
     } 
     $idx ++ 
    } while ($count -gt 0) 
} 
finally { 
    $fromFile.Close() 
} 
+3

этот подход хорошо работал для меня в 6-Гбайт-файле, который мне нужно было разделить в чрезвычайной ситуации, чтобы более эффективно анализировать в небольших кусках. спасибо за размещение! – xinunix

+8

Мне потребовалось несколько проходов, чтобы понять, как этот скрипт действительно работает. Я сделал это, если кому-то это интересно: https://gist.github.com/awayken/5861923 – awayken

+1

Есть ли причина, по которой вы не использовали 'StreamReader'? Чтобы вы могли разделиться с новыми строками? – stej

3

Там же это быстро (и несколько грязный) один вкладыш:

$linecount=0; $i=0; Get-Content .\BIG_LOG_FILE.txt | %{ Add-Content OUT$i.log "$_"; $linecount++; if ($linecount -eq 3000) {$I++; $linecount=0 } } 

Вы можете настроить количество первых строк в партии путем изменения значения жестко запрограммированный 3000.

2

ли это:

FILE 1

Там же это быстро (и несколько грязный) один вкладыш:

$linecount=0; $i=0; 
    Get-Content .\BIG_LOG_FILE.txt | % 
    { 
     Add-Content OUT$i.log "$_"; 
     $linecount++; 
     if ($linecount -eq 3000) {$I++; $linecount=0 } 
    } 

Вы можете настроить количество первых строк в партии путем изменения жестко закодированное значение 3000.

Get-Content C:\TEMP\DATA\split\splitme.txt | Select -First 5000 | out-File C:\temp\file1.txt -Encoding ASCII 

FILE 2

Get-Content C:\TEMP\DATA\split\splitme.txt | Select -Skip 5000 | Select -First 5000 | out-File C:\temp\file2.txt -Encoding ASCII 

FILE 3

Get-Content C:\TEMP\DATA\split\splitme.txt | Select -Skip 10000 | Select -First 5000 | out-File C:\temp\file3.txt -Encoding ASCII 

и т.д ...

+0

спасибо, что я закончил использовать это ... но не забудьте добавить - ширина для outfile или может усечь ваш выход на 80 символов ... также это работает по одной строке за раз ... быстрее использовать gc -readcount 1000 | select -first 5 ... это делает 1000 строк за раз ... наконец, gc будет читать весь файл, а select будет игнорировать большую часть этого ... немного быстрее включить параметр -totalcount с gc, чтобы остановиться после определенного числа строк ... может делать -tail для конца файла тоже – TCC

22

Простой один вкладыш для разделения на основе количества строк (100 в данном случае):

$i=0; Get-Content .....log -ReadCount 100 | %{$i++; $_ | Out-File out_$i.txt} 
5

Многие из этих ответов были слишком медленными для моих исходных файлов. Мои исходные файлы были файлами SQL между 10   МБ и 800   МБ, которые нужно было разделить на файлы с примерно равными подсчетами строк.

Я нашел некоторые из предыдущих ответов, в которых Add-Content используется довольно медленно. Ожидание много часов для раскола до конца было не редкостью.

Я не пробовал Typhlosaurus's answer, но он выглядит только для разделения по размеру файла, а не по количеству строк.

Следующее соответствует моим целям.

$sw = new-object System.Diagnostics.Stopwatch 
$sw.Start() 
Write-Host "Reading source file..." 
$lines = [System.IO.File]::ReadAllLines("C:\Temp\SplitTest\source.sql") 
$totalLines = $lines.Length 

Write-Host "Total Lines :" $totalLines 

$skip = 0 
$count = 100000; # Number of lines per file 

# File counter, with sort friendly name 
$fileNumber = 1 
$fileNumberString = $filenumber.ToString("000") 

while ($skip -le $totalLines) { 
    $upper = $skip + $count - 1 
    if ($upper -gt ($lines.Length - 1)) { 
     $upper = $lines.Length - 1 
    } 

    # Write the lines 
    [System.IO.File]::WriteAllLines("C:\Temp\SplitTest\result$fileNumberString.txt",$lines[($skip..$upper)]) 

    # Increment counters 
    $skip += $count 
    $fileNumber++ 
    $fileNumberString = $filenumber.ToString("000") 
} 

$sw.Stop() 

Write-Host "Split complete in " $sw.Elapsed.TotalSeconds "seconds" 

Для MB файла 54  , я получаю выход ...

Reading source file... 
Total Lines : 910030 
Split complete in 1.7056578 seconds 

Я надеюсь, что другие ищут простой, линии на основе расщепления сценария, который соответствует моим требованиям, будет найти это полезным.

+0

Но это будет потреблять много памяти. Я пытаюсь перезаписать с помощью streamreader/writer –

+0

см. Мой ответ ниже для дружественного к памяти нового раскола на основе строк. –

+0

Если это произойдет через несколько секунд, я не понимаю, почему память является проблемой. Я подождал 10 минут для решения «ответа», чтобы в конечном итоге ничего не добиться, пока я реализовал это решение, и он был завершен чуть более 5 секунд. –

20

Как и все ответы здесь, но с помощью StreamReader/StreamWriter для разделения на новые строки (строка за строкой, вместо того, чтобы сразу же прочитать весь файл в памяти). Этот подход может разделить большие файлы самым быстрым способом, о котором я знаю.

Примечание: У меня очень мало проверок ошибок, поэтому я не могу гарантировать, что он будет работать плавно для вашего случая. Это было для моего (1.7   GB TXT-файл из 4 миллионов строк, разделенных на 100 000 строк на файл за 95 секунд).

#split test 
$sw = new-object System.Diagnostics.Stopwatch 
$sw.Start() 
$filename = "C:\Users\Vincent\Desktop\test.txt" 
$rootName = "C:\Users\Vincent\Desktop\result" 
$ext = ".txt" 

$linesperFile = 100000#100k 
$filecount = 1 
$reader = $null 
try{ 
    $reader = [io.file]::OpenText($filename) 
    try{ 
     "Creating file number $filecount" 
     $writer = [io.file]::CreateText("{0}{1}.{2}" -f ($rootName,$filecount.ToString("000"),$ext)) 
     $filecount++ 
     $linecount = 0 

     while($reader.EndOfStream -ne $true) { 
      "Reading $linesperFile" 
      while(($linecount -lt $linesperFile) -and ($reader.EndOfStream -ne $true)){ 
       $writer.WriteLine($reader.ReadLine()); 
       $linecount++ 
      } 

      if($reader.EndOfStream -ne $true) { 
       "Closing file" 
       $writer.Dispose(); 

       "Creating file number $filecount" 
       $writer = [io.file]::CreateText("{0}{1}.{2}" -f ($rootName,$filecount.ToString("000"),$ext)) 
       $filecount++ 
       $linecount = 0 
      } 
     } 
    } finally { 
     $writer.Dispose(); 
    } 
} finally { 
    $reader.Dispose(); 
} 
$sw.Stop() 

Write-Host "Split complete in " $sw.Elapsed.TotalSeconds "seconds" 

Выход Расщепление 1,7   GB Файл:

... 
Creating file number 45 
Reading 100000 
Closing file 
Creating file number 46 
Reading 100000 
Closing file 
Creating file number 47 
Reading 100000 
Closing file 
Creating file number 48 
Reading 100000 
Split complete in 95.6308289 seconds 
+3

Для тех, кто хотел бы использовать вышеприведенное решение, а также повторять заголовки, вам нужно будет сделать один шаг - $ writer.WriteLine ($ header) после комментария - «Чтение $ linesperFile». $ header будет переменной, которую вам нужно будет объявить со всеми желаемыми столбцами в начальной части кода. Благодаря @Vincent для пылающего быстрого решения – VKarthik

0

Мое требование было немного по-другому. Я часто работаю с файлами с разделителями-запятыми и с разделителями табуляции ASCII, где одна строка является одной записью данных. И они действительно большие, поэтому мне нужно разбить их на управляемые части (при сохранении строки заголовка).

Итак, я вернулся к своему классическому методу VBScript и собрал небольшой скрипт .vbs, который можно запустить на любом компьютере под управлением Windows (он автоматически запускается движком хоста сценария WScript.exe в окне).

Преимущество этого метода состоит в том, что он использует текстовые потоки, поэтому базовые данные не загружаются в память (или, по крайней мере, не все одновременно). В результате это происходит исключительно быстро, и на самом деле не нужно много памяти для запуска.Тестовый файл, который я только что разделил, используя этот скрипт на моем i7, составлял около 1 ГБ в размере файла, имел около 12 миллионов строк текста и был разделен на 25 файлов частей (каждая из которых имела около 500 тыс. Строк каждая) - обработка заняла около 2 минут и он не переходил на 3 МБ памяти, используемой в любой момент.

Предостережение здесь заключается в том, что он опирается на текстовый файл, имеющий «линии» (что означает, что каждая запись разделена CRLF), поскольку объект Text Stream использует функцию «ReadLine» для обработки одной строки за раз. Но, если вы работаете с TSV или CSV-файлами, это прекрасно.

Option Explicit 

Private Const INPUT_TEXT_FILE = "c:\bigtextfile.txt" 
Private Const REPEAT_HEADER_ROW = True     
Private Const LINES_PER_PART = 500000     

Dim oFileSystem, oInputFile, oOutputFile, iOutputFile, iLineCounter, sHeaderLine, sLine, sFileExt, sStart 

sStart = Now() 

sFileExt = Right(INPUT_TEXT_FILE,Len(INPUT_TEXT_FILE)-InstrRev(INPUT_TEXT_FILE,".")+1) 
iLineCounter = 0 
iOutputFile = 1 

Set oFileSystem = CreateObject("Scripting.FileSystemObject") 
Set oInputFile = oFileSystem.OpenTextFile(INPUT_TEXT_FILE, 1, False) 
Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True) 

If REPEAT_HEADER_ROW Then 
    iLineCounter = 1 
    sHeaderLine = oInputFile.ReadLine() 
    Call oOutputFile.WriteLine(sHeaderLine) 
End If 

Do While Not oInputFile.AtEndOfStream 
    sLine = oInputFile.ReadLine() 
    Call oOutputFile.WriteLine(sLine) 
    iLineCounter = iLineCounter + 1 
    If iLineCounter Mod LINES_PER_PART = 0 Then 
     iOutputFile = iOutputFile + 1 
     Call oOutputFile.Close() 
     Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True) 
     If REPEAT_HEADER_ROW Then 
      Call oOutputFile.WriteLine(sHeaderLine) 
     End If 
    End If 
Loop 

Call oInputFile.Close() 
Call oOutputFile.Close() 
Set oFileSystem = Nothing 

Call MsgBox("Done" & vbCrLf & "Lines Processed:" & iLineCounter & vbCrLf & "Part Files: " & iOutputFile & vbCrLf & "Start Time: " & sStart & vbCrLf & "Finish Time: " & Now()) 
0

Похоже, работа для команды раскол UNIX:

split MyBigFile.csv 

Просто разделить мой файл CSV 55 ГБ в 21K куски менее чем за 10 минут.

Это не является родным для PowerShell, хотя, но приходит с, например, мерзавцем для окон пакета https://git-scm.com/download/win

0

Как линии может быть переменным в журналах, я думал, что лучше взять несколько строк в файл подход. Следующий фрагмент кода обрабатывается файл журнал 4000000 линии в возрасте до 19 секунд (18.83 .. секунд) разделив его на 500000 строк кусков:

$sourceFile = "c:\myfolder\mylargeTextyFile.csv" 
$partNumber = 1 
$batchSize = 500000 
$pathAndFilename = "c:\myfolder\mylargeTextyFile part $partNumber file.csv" 

[System.Text.Encoding]$enc = [System.Text.Encoding]::GetEncoding(65001) # utf8 this one 

$fs=New-Object System.IO.FileStream ($sourceFile,"OpenOrCreate", "Read", "ReadWrite",8,"None") 
$streamIn=New-Object System.IO.StreamReader($fs, $enc) 
$streamout = new-object System.IO.StreamWriter $pathAndFilename 

$line = $streamIn.readline() 
$counter = 0 
while ($line -ne $null) 
{ 
    $streamout.writeline($line) 
    $counter +=1 
    if ($counter -eq $batchsize) 
    { 
     $partNumber+=1 
     $counter =0 
     $streamOut.close() 
     $pathAndFilename = "c:\myfolder\mylargeTextyFile part $partNumber file.csv" 
     $streamout = new-object System.IO.StreamWriter $pathAndFilename 

    } 
    $line = $streamIn.readline() 
} 
$streamin.close() 
$streamout.close() 

Это легко может быть превращено в функции или сценарий файл с параметрами, чтобы сделать он более универсален. Он использует StreamReader и StreamWriter для достижения своей скорости и малой занимаемой памяти.

0

Это мое решение для разбиения файла patch6.txt (около 32 000 строк) на отдельные файлы по 1000 строк каждый. Это не быстро, но он выполняет эту работу.

$infile = "D:\Malcolm\Test\patch6.txt" 
$path = "D:\Malcolm\Test\" 
$lineCount = 1 
$fileCount = 1 

foreach ($computername in get-content $infile) 
{ 
    write $computername | out-file -Append $path_$fileCount".txt" 
    $lineCount++ 

    if ($lineCount -eq 1000) 
    { 
     $fileCount++ 
     $lineCount = 1 
    } 
} 
Смежные вопросы