Как извлечь часть строки и сохранить ее в новом текстовом файле (findstr или другой инструмент) - PullRequest
0 голосов
/ 30 марта 2020

У меня есть txt файл с 500 млн строк (более 100 ГБ)

Data: xxxx
Lng: Java:version- xxxx
Code: xxx
Data: xxxx
Lng: Java:version- xxxx
Code: xxx
Data: xxxx
Lng: Java:version- xxxx
Code: xxx
Data: xxxx
Lng: Java:version- xxxx
Code: xxx
Data: xxxx
Lng: Java:version- xxxx
Code: xxx
Data: xxxx
Lng: Java:version- xxxx
Code: xxx

Я хочу извлечь часть первого, четвертого, седьмого, десятого, тринадцатого, шестнадцатого и т. Д. c. и др c. линия Как это сделать? На данный момент я использовал findstr (отличный, очень быстрый инструмент), но он извлекает всю строку со всей строкой, и мне нужна только часть строки из этих строк, вот мой код

findstr Data data.txt > done.txt

, но когда я запускаю этот код у меня есть

Data: xxxx
Data: xxxx
Data: xxxx
Data: xxxx

вместо:

xxxx
xxxx
xxxx
xxxx

Как извлечь просто «xxxx» в новый файл, чтобы «сэкономить место на моем жестком диске»:)?

Ответы [ 2 ]

1 голос
/ 30 марта 2020

findstr имеет только небольшое подмножество REGEX, а всегда возвращает всю строку. Вам нужно разделить его на for /f l oop. Вы хотите, чтобы второй токен был разделен пробелом (это один из разделителей по умолчанию, поэтому вам не нужно определять его явно). Если быть точным, то что угодно после первого токена (*):

(for /f "tokens=1,*" %%a in ('findstr /b "Data:" data.txt') do echo %%b) > done.txt

Примечание: весь вывод for /f l oop перенаправляется в один go, что является большим экономия времени с большими файлами. Если вы пишете каждую строку отдельно, файл должен быть открыт, прочитан до конца файла, записан и снова закрыт для каждой отдельной строки. Чем больше файл, тем больше экономится время (оно увеличивается до нескольких сотен или даже тысяч с очень большими файлами)

1 голос
/ 30 марта 2020

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

Для сопоставления строк, которые начать с Data: вы можете использовать что-то вроде этого ...

findstr /R "^Data:" data.txt

Это разбивается следующим образом:

  • ^ - начало строки (в случае Data: может появиться где-нибудь еще в строке)
  • Data: - Дословный текст Data:

Возвращает всю строку, включая префикс Data:. Чтобы убрать префикс, можно использовать выражение вроде этого ...

(?<=^Data:).*

..., но, очевидно, findstr не поддерживает (?<=) положительное утверждение за кадром. PowerShell выполняет , который можно использовать, вставив и выполнив следующее в приглашении PowerShell ...

Select-String -Pattern '(?<=^Data:\s+).*' -Path 'data.txt' `
    | ForEach-Object -Process { $_.Matches[0].Value } `
    | Set-Content -Path 'done.txt' -Encoding 'UTF8'

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

Get-Content -Path 'data.txt' `
    | Where-Object { $_ -like 'Data:*' } `
    | ForEach-Object -Process {
        # Find the index of the first non-whitespace character after "Data:"
        # This avoids allocating another [String] with $_.TrimStart() or $_.Trim()
        for ($startIndex = 5; [Char]::IsWhiteSpace($_[$startIndex]); $startIndex++)
        {
            # Incrementing $startIndex is the job of this loop, so no body necessary
        }

        return $_.Substring($startIndex)
    } | Set-Content -Path 'done.txt' -Encoding 'UTF8'
...