dimayakovlev.ru


Как пронумеровать строки в текстовом файле при помощи PowerShell

Если в текстовом файле хранится информация, которую надо представить в виде нумерованного списка, можно открыть файл в текстовом редактор и вручную проставить номера строк. Если файл один, а строк в нём не много, то не составит труда сделать это вручную. В остальных случаях лучше автоматизировать процесс. Рассказываю как сделать это при помощи PowerShell.

Итак, стоит задача автоматически пронумеровать строки из текстового файла, пропуская пустые строки и строки содержающие только символы пробела, а результат с пронумерованными строками сохранить в файл.

Всё это сделает следующий код сценария на PowerShell.

$pathInputFile = 'Original.txt'
$pathOutputFile = 'Numbered.txt'
$lineNumber = 1
$content = Get-Content -Path $pathInputFile
for ($i=0; $i -lt $content.Length; $i++) {
  if ($content[$i] -match '\S') {
    $content[$i] = "$lineNumber. $($content[$i])"
    $lineNumber++
  }
}
Set-Content -Path $pathOutputFile -Value $content

В этом примере кода в переменных $pathInputFile и $pathOutputFile задаются пути к оригинальному текстовому файлу и к файлу с пронумерованными строками. При помощи командлета Get-Content в переменную $content считывается содержимое оригинального текстового файла, которое, затем перебирается в цикле for. Каждая строка, хранящаяся в переменной $content, проверяется с использованеми регулярного выражения. Если строка содержит символы, отличные от пробелов, к строке добавляется номер из переменной $lineNumber, а значение переменной увеличиватся на 1. После завершение выполнения цикла for содержимое переменной $content при помощи командлета Set-Content сохраняется в текстовый файл по пути из переменной $pathInputFile.

При необходимости можно не создавать новый текстовый файл, а сохранить содержимое с пронумерованными строками в исходный файл. Для этого в параметре -Path командлета Set-Content вместо переменной $pathOutputFile следует использовать переменную $pathInputFile.

Если задача повторяется регулярно, будет удобнее написать функцию на PowerShell, добавив в неё дополнительные возможности.

Function Add-LineNumbers {
  [CmdletBinding()]
  [OutputType([Object[]])]
  param (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True
    )]
    [Object[]]
    $Value,
    [Int]
    $FirstLineNumber = 1,
    [string]
    $Delimeter = '. '
  )
  begin {
    $lineNumber = $FirstLineNumber
  }
  process {
    for ($i=0; $i -lt $Value.Length; $i++) {
      if ($Value[$i] -match '\S') {
        $Value[$i] = "$lineNumber$Delimeter$($Value[$i])"
		$lineNumber++
      }
    }
    return $Value
  }
}

Приведённая функция, названная в примере Add-LineNumbers, принимает три параметра:

  • -Value - обязательный параметр, тип Object[] - массив строк, которые подлежат нумерации;
  • -FirstLineNumber - необязательный параметр, тип Integer - начальный номер для нумерации первой строки, по умолчанию равен 1;
  • -Delimeter - необязательный параметр, тип string - строка-разделитель, отделяющая номер строки от текста строки, по умолчанию имеет значение . (точка и пробел).

Для использования функции в конвейре в коде используются блоки begin и process.

В остальном логика функции Add-LineNumbers повторяет логику, рассмотренную в первом примере сценария PowerShell.

В следующих примерах показаны разные варианты вызова функции Add-LineNumbers.

# Вызов функции Add-LineNumbers с выводом результата в консоль.
# В качестве разделителя используется символ закрывающей скобки и пробел.
Add-LineNumbers -Value (Get-Content -Path 'C:\Text.txt') -Delimeter ') '

# Вызов функции Add-LineNumbers с сохранение результата в переменную.
# Нумерация строк начинается со 100.
$numbered = Add-LineNumbers -Value (Get-Content -Path 'C:\Text.txt') -FirstLineNumber 100

# Вызов функции Add-LineNumbers с сохранение результата в указанный текстовый файл.
Set-Content -Path 'C:\Numbered.txt' -Value (Add-LineNumber -Value (Get-Content -Path 'C:\Text.txt'))

# Вызов функции Add-LineNumbers в конвейере.
# В результате выполнения оригинальное содержимое текстового файла перезаписывается.
Get-Content -Path 'C:\Text.txt' | Add-LineNumbers | Set-Content -Path 'C:\Text.txt'

Добавьте функцию Add-LineNumbers в свой файл профиля PowerShell и используйте при необходимости.