Назад | Перейти на главную страницу

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

Мне нужно извлечь часть текстового файла между двумя пустыми строками. Текстовый файл выглядит примерно так ...

This is line 01 of the text file.
This is line 02 of the text file.
This is line 03 of the text file.

This is line 05 of the text file.
This is line 06 of the text file.
This is line 07 of the text file.
     > VALUE TO SEARCH <
This is line 09 of the text file.
This is line 10 of the text file.

This is line 12 of the text file.
This is line 13 of the text file.

Итак, я могу выполнить поиск и найти «> ЗНАЧЕНИЕ ДЛЯ ПОИСКА <» в текстовом файле, но тогда мне нужно будет захватить все, вплоть до предыдущей пустой строки, и все, вплоть до конечной пустой строки этого единственного раздела. Имеет ли это смысл? В любом случае количество строк в разделе различается, но между разделами всегда есть одна пустая строка.

Можно ли это сделать с помощью командного файла? Если да, то как?

Заранее спасибо!

Чистый пакет Windows не очень хорош в обработке текста.

Я бы использовал свой Утилита обработки текста регулярных выражений JREPL.BAT для этой задачи. Это чистый сценарий (гибридный JScript / пакетный), который изначально запускается на любой машине Windows, начиная с XP. Полная документация доступна, выполнив jrepl /? из командной строки.

Вот решение с использованием JREPL.BAT. Обратите внимание, что поиск является регулярным выражением, поэтому вам придется экранировать символы поиска в VALUE TO SEARCH, которые являются метасимволами регулярного выражения. Команда читает "test.txt" и записывает результат в "out.txt"

jrepl "([^\r\n]+\r?\n)*.*VALUE TO SEARCH.*\n?([^\r\n]+\r?\n?)*" "$0" /jmatch /m /f test.txt /o out.txt

Вы должны использовать CALL JREPL если вы поместите команду в пакетный сценарий.

Это можно решить, используя чистый пакетный анализ, но это сложно и гораздо менее эффективно (намного медленнее). Вот одно решение.

@echo off
setlocal enableDelayedExpansion

set "infile=test.txt"
set "outfile=out.txt"
set "find=VALUE TO SEARCH"

set "emptyFile=empty.txt"

:: Compute end of file as number of lines + 1
for /f %%N in ('find /c /v "" ^<"%infile%"') do set /a last=%%N+1

:: Get list of line numbers of empty lines and append end of file
>"%emptyFile%" (
  for /f "delims=:" %%N in ('findstr /n "^$" "%infile%"') do echo %%N
  echo !last!
)

<"%infile%" >"%outFile%" (
  set /a last=1

  %= iterate list of found line numbers, ignoring lines that have already been printed =%
  for /f "delims=:" %%A in ('findstr /nc:"!find!" "!infile!"') do if %%A geq !last! (

    %= Locate beginning and end of found section, and compute lines to skip =%
    set /a beg=0
    set "end="
    for /f "usebackq" %%B in ("%emptyFile%") do if not defined end (
      if %%B gtr %%A (set /a end=%%B, start=beg+1, stop=end-1) else set beg=%%B
    )

    %= Skip lines until beginning of found section =%
    for /l %%N in (!last! 1 !beg!) do set /p "ln="

    %= Write empty line delimiter if not first found section =%
    if !last! gtr 1 (echo()

    %= Read and write found section =%
    for /l %%N in (!start! 1 !stop!) do (
      set /p "ln="
      (echo(!ln!)
    )

    set /a last=end
  )
)

del "%emptyFile%"

Приведенное выше чистое пакетное решение имеет следующие ограничения:

  • Строки должны иметь длину <= 1021 байт.
  • Управляющие символы будут удалены из конца каждой строки
  • Каждая строка должна заканчиваться \r\n (В стиле Windows). Не будет работать с \n (Стиль Unix).