Как извлечь конкретную строку из текстового файла - PullRequest
1 голос
/ 04 октября 2019

Я получил большой файл журнала (user.log), например:

   2019-10-02 00:03:55.407095
   2019-10-02 00:03:55.410345
   2019-10-02 00:03:55.410765
   2019-10-02 00:03:55.411187
   2019-10-02 00:03:55.411791
   2019-10-02 00:03:55.412657

Как мне просто извлечь номер строки № 3 из файла журнала как;

2019-10-02 00: 03: 55.410765

При использовании сценария powershell?

Ответы [ 2 ]

2 голосов
/ 04 октября 2019

A простой и энергосберегающий подход, подходящий для обработки большие входные файлы - объединение Get-Content с Select-Object:

Get-Content user.log | Select-Object -Skip 2 -First 1
  • -Skip 2 предписывает Select-Object пропустить первые две строки ввода на Get-Content.

  • Следовательно, это 3-я строка , которая обрабатывается первой и выводится на Select-Object, а
    -First 1 делает ее остановкой обработки сразу после этого, так что остальная часть файла не должна бытьчитать.


A быстрее сближение , ЕСЛИ часть файла до нужного номера строки равна достаточно маленький до вписывается в память в целом :

(Get-Content -TotalCount 3 -ReadCount -3 user.log)[-1]
  • -TotalCount 3 говорит Get-Content прочитать 3 строки(не более) всего.

    • -ReadCount 3 дополнительно сообщает Get-Content о том, что все 3 строки должны считываться сразу в массив и отправлять его по конвейеру какодин объект - вместо строка by строка - это не необходимо , но ускоряет команду.
  • [-1], затем извлекает последний элемент из результирующего массива, который является 3-й строкой.


Если входной файл в целом мала, следующее решение простейшее :

(Get-Content user.log)[2]  # add -ReadCount 0 to speed things up

То есть Get-Content читает все строк, которые (...) собирает вмассив в памяти, и [2] обращается к массиву 3-й элемент , то есть 3-я строка.

Простой способ ускорить это решение - добавить -ReadCount 0, что заставляет Get-Content выдавать массив всех входных строк как отдельный объект вывода , в отличие отчтобы испускать строки одна за другой и позволить (...) собрать их в массив впоследствии.

0 голосов
/ 04 октября 2019

Вы можете попробовать это и изменить переменную $ target на любую строку, которую вы хотите извлечь:

$content = Get-Content "path to user.log"
$count = 0
$target = 3

foreach ($line in $content) {
    $count += 1
    if ($count -eq $target) {
        $line
        break
    }
}
...