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

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

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

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

setlocal enabledelayedexpansion
setlocal enableextensions
set live_svn_access_file=c:\csvn\data\conf\svn_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 && 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:\csvn\data\conf\svn_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 && goto error-handler
if ["%skip%"] LSS ["1"] set error=Number of lines to skip was less than 1, this will most likely fail && 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
)

person Niklas J. MacDowall    schedule 25.10.2011    source источник
comment
Строка if not defined read-input echo. >> %of% создает строку с одним пробелом вместо пустой строки, вы можете изменить ее на (>> %of% echo.). Вам следует избегать echo., это медленно и может дать сбой, лучше использовать echo(. Опция skip=%skip% не работает, если %skip% равно нулю   -  person jeb    schedule 26.10.2011
comment
Я изменил сценарий, чтобы он соответствовал вашим предложениям, убедитесь, что я правильно вас понял.   -  person Niklas J. MacDowall    schedule 26.10.2011
comment
ИМХО, теперь ваш код должен работать стабильно   -  person jeb    schedule 28.10.2011
comment
@Niklas Вы видите удаление восклицательных знаков из исходного файла? У меня есть вариант этого, и я все еще вижу эту проблему.   -  person Jared    schedule 28.10.2011
comment
@Jared Я не тестировал восклицательные знаки, так как они все равно не появятся в моем файле.   -  person Niklas J. MacDowall    schedule 31.10.2011


Ответы (1)


У вас есть две основные проблемы: FOR /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
)
person jeb    schedule 25.10.2011
comment
Спасибо, но я не могу использовать команду (findstr) внутри цикла for, это должен быть файл, потому что я использую опцию Skip для пропуска некоторых строк. - person Niklas J. MacDowall; 25.10.2011
comment
Вы также можете использовать опцию пропуска с этой конструкцией - person jeb; 25.10.2011
comment
Я попробую это. Спасибо. Кстати, правильно ли закрыто echo(!var!? - person Niklas J. MacDowall; 26.10.2011
comment
Да echo( это лучший способ без проблем эхо даже пустой строки и избежать вывода ECHO включено - person jeb; 26.10.2011
comment
@jeb: Извините. Чтобы показать пустую строку с командой echo, можно использовать любой неиспользуемый специальный символ. Я настоятельно рекомендую не использовать символы, которые уже используются для других целей, такие как .() и т. д. Я предлагаю использовать дефис, который уже используется во многих командах, для обозначения параметров команды: echo/. :) - person Aacini; 02.11.2011
comment
echo(!var! должны обрабатывать пустые строки, а также /? или on и другое содержимое в !var!. Ваша версия echo/ не работает с одним ? - person jeb; 02.11.2011
comment
@jeb: Да, ты прав! Я никогда не задумывался об этом случае... Тем не менее, я все еще думаю, что ( не подходит, потому что это мешает просмотру программы со скобками. Возможно, мы могли бы использовать стандартные разделители ,;= или :` (I like echo`), что вы думаете? Я извиняюсь за все это, но я думаю, что важно, чтобы мы договорились об этом в стандарте ;-) - person Aacini; 02.11.2011
comment
@jeb: Извините, в моем веб-доступе произошла ошибка, когда я редактировал свой предыдущий комментарий... Предлагаю использовать обратную косую черту: `echo\` - person Aacini; 02.11.2011
comment
«Эхо» также не работает, но, возможно, вам лучше открыть новый вопрос - person jeb; 02.11.2011
comment
Я нашел старый ответ на эту тему SO: экранирование эха командного файла, начинающегося с /? - person jeb; 03.11.2011