Я нашел ответ Джеба, который копирует файл в другой файл, включая пустые строки, добавляя число: в начало каждой строки -
(
set taglinelinks=one two three
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims = " %%a in (`"findstr /n ^^ overview.md"`) do (
set "var=%%a"
if "%var:~0,2%" == "5:" (echo %taglinelinks%)
SETLOCAL EnableDelayedExpansion
set "var=!var:*:=!"
echo(!var!
)
) > new.txt
Я добавил переменную вверху для тестирования и добавил строку «если». Он отлично работает без строки «если», но я не вижу ничего плохого в этой строке. Я проверяю, равен ли номер строки 5, и если это эхо-переменная в файл, то продолжайте. У меня должна быть команда else в моем операторе if, но прямо сейчас я не могу определить, что туда поместить, чтобы остальная часть кода не пропускала исходное содержимое строки 5.
Вы можете попробовать это так:
@Echo Off
Set "taglinelinks=one two three"
( For /F "Tokens=1*Delims=:" %%A in ('Findstr /N "^" "overview.md"')Do (
If %%A NEq 5 (Echo=%%B)Else Echo %taglinelinks%
)
)>"new.txt"
Вы, должно быть, попробовали это, прежде чем я отредактировал свой ответ, чтобы добавить =
, попробуйте еще раз!
Это один из рекомендуемых символов для использования после Echo
, чтобы предотвратить вывод статуса Echo
. Тесты показали, что (
. /
и =
были лучше, чем обычный символ .
, используемый большинством людей. Я предпочитаю использовать (
или =
, и в данном случае выбрал последний, потому что считаю, что он лучше смотрится в короткой строке, заключенной в паретезы.
Я заметил, что если я использую !taglinelinks!
вместо %taglinelinks%
, я теряю первый !
в строке.
Я не устанавливал и не использовал отложенное расширение, потому что оно не нужно. Отложенное расширение необходимо только тогда, когда значение переменной изменяется в блоке кода, никакая переменная не изменяется, так как метапеременные из блока For
выполняют свою работу. %taglinelinks%
был установлен до блока For
и не изменялся в нем, так почему вы чувствуете необходимость использовать форму переменной с отложенным расширением? Если вы хотите использовать отложенное расширение и предотвратить потерю строк, которые могут начинаться с одного или нескольких символов :
, выберите вместо этого использовать ответ от @aschipfl.
В этом ответе я придерживаюсь нашего исходного кода и сосредотачиваюсь на недостатках. В основном мне нравится этот подход (конечно, с исправлением ошибок), потому что он может правильно обрабатывать даже строки, начинающиеся с двоеточия :
, и у него нет проблем с появлением !
в текстовом файле, поскольку включено отложенное раскрытие.
Так или иначе, сначала я хочу показать адаптированный и работающий код:
@echo off
setlocal DisableDelayedExpansion
set "taglinelinks=one two three"
> "new.txt" (
for /F "delims = " %%a in ('findstr /N "^" "overview.md"') do (
set "var=%%a"
setlocal EnableDelayedExpansion
if "!var:~,2!" == "5:" (
echo(!taglinelinks!
) else (
echo(!var:*:=!
)
endlocal
)
)
endlocal
И вот что я исправил:
if
должно быть в блоке с включенным отложенным расширением, поэтому я переместил его на одну строку вниз и заменил %
на !
;else
так, чтобы оно содержало оставшуюся часть кода в теле цикла for /F
.endlocal
, поэтому вы не можете столкнуться с ограничениями вложенности setlocal
, а командная строка set "var=%%a"
фактически появляется в разделе кода с отключенным отложенным расширением, что необходимо, чтобы не создавать проблем с появлением !
в файле;И вот некоторые мелкие и косметические изменения:
@echo off
сверху, чтобы избежать записи эха команд в new.txt
;setlocal
наверх, чтобы сначала отключить отложенное расширение, поэтому !
можно было даже безопасно использовать в перенаправленном имени файла и в первой командной строке set
(поскольку мы могли не знать, отключено ли отложенное расширение или включено ранее );set
в кавычках также для присвоения переменной taglinelinks
, чтобы сделать его безопасным; затем я переместил эту строку за пределы блока перенаправления, чтобы она стала более очевидной;usebackq
не обязательна, поэтому я убрал ее и использовал одинарные кавычки ''
(но тут дело вкуса);findstr
выглядит немного странно, особенно экранированный знак вставки ^^
, поэтому я изменил кавычки, чтобы строка поиска, а также путь к файлу были заключены в кавычки, поэтому такое экранирование больше не требуется, и имя файла может даже содержать пробелы или другие специальные символы;taglinelinks
не находится в блоке, где включено отложенное раскрытие; это позволяет переменной содержать даже специальные символы;set "var=!var:*:=!"
на самом деле не нужно, поэтому я удалил его и сразу повторил усеченную строку;if
/else
, чтобы улучшить читабельность;> "new.txt"
в начало внешнего блока в скобках, чтобы сделать его более заметным (но это опять же просто вопрос вкуса), и я заключил имя файла в двойные кавычки, так что оно может даже содержать пробелы или что-то другое. специальные символы;endlocal
, которая принадлежит начальной setlocal
;Есть еще одна вещь, которая мне не нравится в скрипте, а именно негибкий способ определения номера текущей строки, потому что на данный момент он работает только для чисел меньше 10
, немного не адаптируя код.
Вот способ гибко указать номер строки для замены:
@echo off
setlocal DisableDelayedExpansion
set "taglinelinks=one two three"
set "linenumber=5"
> "new.txt" (
for /F "delims = " %%a in ('findstr /N "^" "overview.md"') do (
set "var=%%a"
setlocal EnableDelayedExpansion
set /A "num=var"
if !num! equ !linenumber! (
echo(!taglinelinks!
) else (
echo(!var:*:=!
)
endlocal
)
)
endlocal
Вот что я сделал:
linenumber
с номером строки 5
; учитывать, что linenumber
не должно содержать ведущих нулей, чтобы число не интерпретировалось как восьмеричное целое число позже (по if
);set /A "num=var"
, который использует неявное расширение переменной set /A
, что означает, что строка строки сканируется слева направо до первого нечислового символа1, затем эта строка преобразуется в целое число и, наконец, присваивается num
; это означает, что файл содержит менее 231 строк;if
изменено на if !num! equ !linenumber!
, которое выполняет числовое сравнение из-за equ
, поскольку оба выражения являются целыми числами; так что это больше не зависит от количества цифр номера строки; здесь я мог бы также использовать %linenumber%
, так как переменная не изменяется в блоке кода, но я решил использовать !linenumber!
, чтобы покрыть случай неправильной инициализации этой переменной (особенно, когда она пуста или содержит специальные символы из-за опечаток);1) Actually leading SPACEs and TABs are ignored. Next a single +
or -
sign may occur. Then everything up to the next non-numeric figure is used to convert the string into a signed 32-bit integer. If the result cannot be represented as such it becomes coerced.
Я получаю «Эхо выключено» вместо пустых строк.