Удалите многострочные строки из текстового файла, используя пакетный скрипт - PullRequest
1 голос
/ 19 июля 2010

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

LINE ENTRY KEEP_1 BLA BLA
END
LINE ENTRY REMOVE_1 FOO BAR
END
LINE ENTRY REMOVE_2 HELLO WORLD
END
LINE ENTRY KEEP_2 CAT DOG
END

После запуска пакетного скрипта мне требуется, чтобы новый файл содержал

LINE ENTRY KEEP_1 BLA BLA
END
LINE ENTRY KEEP_2 CAT DOG
END

, где была удалена любая строка, содержащая REMOVE_а также соответствующая строка 'END'.

Я пытался использовать найденную технику здесь , чтобы удалить строки, содержащие строку, но оказалось невозможным включить такие символы, как \r \ n, чтобы проверить и включить «END» в поиск.Я не могу сделать это как две отдельные команды FINDSTR, так как мне все еще требуется сохранить текст «END» для двух других записей.Использование findstr /v REMOVE_ оставляет мне следующее:

LINE ENTRY KEEP_1 BLA BLA
END
END
END
LINE ENTRY KEEP_2 CAT DOG
END

, а использование findstr /v "REMOVE_*\r\nEnd", похоже, не работает вообще.Просто чтобы подтвердить, что каждая строка определенно заканчивается на \r\n.

Любая помощь по этому вопросу будет принята с благодарностью.

Ответы [ 2 ]

3 голосов
/ 19 июля 2010

Следующий пакетный скрипт должен делать то, что вы хотите:

@echo off
setlocal enabledelayedexpansion

set /A REMOVE_COUNT=1

if "%~2"=="" (
    echo Usage: %~n0 search_str file
    echo remove lines that contain a search_str and remove %REMOVE_COUNT% line^(s^) directly after that
    exit /b 1
)

set "SEARCH_STR=%~1"
set "SRC_FILE=%~2"

set /A SKIP_COUNT=0
for /F "skip=2 delims=[] tokens=1,*" %%I in ('find /v /n "" "%SRC_FILE%"') do (
    if !SKIP_COUNT! EQU 0 (
        set SRC_LINE=%%J
        if defined SRC_LINE (
            if "!SRC_LINE:%SEARCH_STR%=!" == "!SRC_LINE!" (
                echo.!SRC_LINE!
            ) else (
                set /A SKIP_COUNT=%REMOVE_COUNT%
            )
        ) else (
            rem SRC_LINE is empty
            echo.
        )
    ) else (
        set /A SKIP_COUNT-=1
    )
)

Количество строк, которые будут удалены после совпавшей строки, можно настроить, установив переменную REMOVE_COUNT.

Сценарий также правильно обрабатывает файлы с пустыми строками, используя хитрость: команда find используется для добавления всех строк к числу строк. Таким образом, команда for не будет пропускать пустые строки.

1 голос
/ 19 июля 2010

findstr работает по линиям.Вы не можете делать с ним ничего, что занимает более одной строки.

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

set remove=
for /f %%x in (file.txt) do (
  if not defined remove (
    echo %%x|findstr "REMOVE" >nul 2>&1 && set remove=1
    if not defined remove echo.%%x
  ) else (
    set remove=
  )
)

(не проверено, но может работать).Проблема здесь двоякая: for /f удаляет все пустые строки из выходных данных, поэтому, если они были в вашем файле до того, как они будут у вас впоследствии.Это может или не может быть проблемой для вашего конкретного случая.Другая проблема заключается в том, что работа со специальными персонажами может стать волосатой.Я не даю никаких гарантий, что все вышеперечисленное работает как следует для таких вещей, как >, <, &, |, ...

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...