Пакет: поиск строки, чтобы пропустить строки выше и записать результаты в новый файл

#windows #batch-file #for-loop #blank-line

#Windows #пакетный файл #for-цикл #пустая строка

Вопрос:

Я успешно написал скрипт, который принимает строку для поиска в определенном файле, а затем выводит строку, в которой она встречается впервые, а затем я беру это значение в цикл for и пропускаю синтаксический анализ этого количества строк и записываю его содержимое в новый файл. Однако я не получаю пустых строк, которые я нахожу довольно проблематичными для решения.

Строка, которую я ищу, — это «/]», кэширует номер строки, в которой он встречается, затем преобразует его в переменную с разделением запятой. Затем я снова беру эту переменную в цикл for и извлекаю первое встречающееся значение в качестве моей окончательной переменной «пропустить это количество строк», которую я затем использую в нижнем цикле for, который снова считывает этот файл и записывает его значения в новые файлы и пропускает это количество строк одновременно.начало файла.

Итак, вот часть скрипта, которая выполняет то, что я описал выше:

 setlocal enabledelayedexpansion
setlocal enableextensions
set live_svn_access_file=c:csvndataconfsvn_access_file
set of=c:test.txt

for /f "Tokens=1 Delims=:" %%i in ('findstr /n /c:"/]" %live_svn_access_file%') do (
    rem cache value in a variable
    set line=%%i
    rem accumulate data to one variable
    if defined line set skip=!skip!, !line!
)
rem strip first two characters in variable ", "
set skip=!skip:~2!
rem strip everything except first value in array
for /f "Tokens=1 Delims=," %%i in ('echo !skip!') do (
    rem store value in a variable
    set skip=%%i
)
rem calculate lines - 1 (arithmetic)
set /a skip=!skip!-1
set skip=!skip!

if not defined skip set error=Could not automatically find which parts to skip from live svn_access_file amp;amp; goto error-handler

for /f "Tokens=* Delims= Skip=%skip%" %%i in (%live_svn_access_file%) do (
    rem cache value in a variable
    set read-input=%%i
    rem write and append content of variable to output-file
    echo !read-input! >> %of%
)
 

Я переписал сценарий, чтобы он соответствовал рабочему, это измененный сценарий:

 setlocal enabledelayedexpansion
setlocal enableextensions
set live_svn_access_file=c:csvndataconfsvn_access_file
set of=c:test.txt

for /f "Tokens=1 Delims=:" %%i in ('findstr /n /r /c:"[..*]" %live_svn_access_file%') do (
    rem cache value in a variable
    set line=%%i
    rem accumulate data to one variable
    if defined line set skip=!skip!, !line!
)
rem take the 2nd sections linenumber into a variable, skipping the first [*foo*]
for /f "Tokens=2 Delims=," %%i in ('"echo !skip!"') do (
    rem store value in a variable
    set skip=%%i
)
rem add 1 line to skip from retrieved value
set /a skip=!skip!-1

rem verify that number of lines to skip has been successfully retrieved, if not go to error-handler
if not defined skip set error=Could not automatically find which parts to skip from live svn_access_file amp;amp; goto error-handler
if ["%skip%"] LSS ["1"] set error=Number of lines to skip was less than 1, this will most likely fail amp;amp; goto error-handler

rem read live svn_access_file, but skip X-lines and write to output-file
setlocal DisableDelayedExpansion
for /f "usebackq Delims= Skip=%skip%" %%i in (`"findstr /n ^^ %live_svn_access_file%"`) do (
    rem cache value in a variable
    set read-input=%%i
    rem write and append content of variable to output-file
    setlocal EnableDelayedExpansion
    rem strip line number prefix
    set read-input=!read-input:*:=!
    rem write read lines to output-file
    echo(!read-input!>>%of%
    endlocal
)
 

Комментарии:

1. Строка if not defined read-input echo. >> %of% выдает строку с одним пробелом вместо пустой строки, которую вы могли бы изменить (>> %of% echo.) . Вы должны избегать echo. медленного и может произойти сбой, лучше использовать echo( . skip=%skip% Опция завершится ошибкой, если %skip% равно нулю

2. Я изменил сценарий в соответствии с вашими предложениями, пожалуйста, убедитесь, что я правильно вас понял.

3. ИМХО, теперь ваш код должен работать стабильно

4. @Niklas Вы видите удаление восклицательных знаков из вашего исходного файла? У меня есть вариант этого, и я все еще вижу эту проблему.

5. @Jared Я не тестировал с восклицательными знаками, так как они все равно не будут встречаться в моем файле.

Ответ №1:

У вас две основные проблемы: a ДЛЯ / F не может читать пустые строки (как вы обнаружили), и если вы используете отложенное расширение, у вас возникли проблемы с восклицательными знаками и каретками в строке set read-input=%%i .

Вы можете решить обе проблемы: пустые строки с добавлением к каждой строке номера строки с помощью findstr . Второй с технологией отложенного переключения.

 SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ t.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!" This removes the prefix
    echo(!var!
    ENDLOCAL
)
 

Комментарии:

1. Спасибо, но я не могу использовать команду (findstr) внутри цикла for, это должен быть файл по причине, по которой я использую опцию «Пропустить», чтобы пропустить некоторые строки.

2. Вы также можете использовать опцию skip-option с этой конструкцией

3. Я попробую это. Спасибо. Кстати, это echo (!var! закрыто правильно?

4. Да, «echo (» — лучший способ без проблем повторить даже пустую строку и избежать вывода «ECHO включено»

5. @jeb: Да, вы правы! Я никогда не думал об этом случае… Тем не менее, я все еще считаю, что ( этого недостаточно, поскольку это мешает просмотру программы в круглых скобках. Возможно, мы могли бы использовать стандартные разделители ,;= или :` (I like echo`), что вы думаете? Я прошу прощения за все это, но я думаю, что важно, чтобы мы согласились в стандарте по этому вопросу 😉