Пакет DOS для цикла с FIND.exe удаляет пустые строки?
этот пакетный скрипт DOS удаляет пустые строки и не показывает пустые строки в файле, хотя я использую тип.exe команда для преобразования файла, чтобы убедиться, что файл ASCII так, что команда FIND совместим с файлом. Может ли кто-нибудь сказать мне, как заставить этот скрипт включать пустые строки?
@ECHO off
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE.exe "build.properties" ^| FIND.exe /V ""`) DO (
ECHO --%%A--
)
pause
5 ответов
это разработанное поведение FOR / F - оно никогда не возвращает пустые строки. Работа заключается в использовании FIND или FINDSTR для префикса строки с номером строки. Если вы можете гарантировать, что строки не начинаются с разделителя номера строки, вы просто установите соответствующий разделитель и сохраните токены 1*, но используйте только 2-й токен.
::preserve blank lines using FIND, assume no line starts with ]
::long lines are truncated
for /f "tokens=1* delims=]" %%A in ('type "file.txt" ^| find /n /v ""') do echo %%B
::preserve blank lines using FINDSTR, assume no line starts with :
::long lines > 8191 bytes are lost
for /f "tokens=1* delims=:" %%A in ('type "file.txt" ^| findstr /n "^"') do echo %%B
::FINDSTR variant that preserves long lines
type "file.txt" > "file.txt.tmp"
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" "file.txt.tmp"') do echo %%B
del "file.txt.tmp"
Я предпочитаю FINDSTR - это более надежно. Например, FIND может усекать длинные строки - FINDSTR не так долго, как он читает непосредственно из файла. FINDSTR отбрасывает длинные строки при чтении из stdin через канал или перенаправление.
Если файл может содержать строки, начинающиеся с разделителя, то необходимо сохранить всю строку с префиксом номера строки, а затем использовать search and replace для удаления префикса строки. Вероятно, вы хотите отключить отложенное расширение при передаче %%A в переменную среды, в противном случае любой ! будет испорчен. Но позже в цикле вам понадобится отложенное расширение, чтобы выполнить поиск и заменять.
::preserve blank lines using FIND, even if a line may start with ]
::long lines are truncated
for /f "delims=" %%A in ('type "file.txt" ^| find /n /v ""') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*]=!"
echo(!ln!
endlocal
)
::preserve blank lines using FINDSTR, even if a line may start with :
::long lines >8191 bytes are truncated
for /f "delims=*" %%A in ('type "file.txt" ^| findstr /n "^"') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
echo(!ln!
endlocal
)
::FINDSTR variant that preserves long lines
type "file.txt" >"file.txt.tmp"
for /f "delims=*" %%A in ('findstr /n "^" "file.txt.tmp"') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
echo(!ln!
endlocal
)
del "file.txt.tmp"
Если вам не нужно беспокоиться о преобразовании файла в ASCII, то более эффективно удалить канал и позволить FIND или FINDSTR открыть файл, указанный в качестве аргумента, или с помощью перенаправления.
существует еще одна работа, которая полностью обходит FOR / F во время процесса чтения. Это выглядит странно, но это более эффективно. Ограничений на использование отложенного расширения нет, но, к сожалению, у него есть и другие ограничения.
1) линии должен быть завершен
2) строки должны быть длиной
3) любые конечные управляющие символы удаляются из каждой строки.
4) он должен читать из файла - вы не можете использовать трубы. Поэтому в вашем случае вам нужно будет использовать файл temp для преобразования в ASCII.
setlocal enableDelayedExpansion
type "file.txt">"file.txt.tmp"
for /f %%N in ('find /c /v "" ^<"file.txt.tmp"') do set cnt=%%N
<"file.txt.tmp" (
for /l %%N in (1 1 %cnt%) do(
set "ln="
set /p "ln="
echo(!ln!
)
)
del "file.txt.tmp"
Я написал очень простую программу, которая может служить в качестве замены FIND
и FINDSTR
команды, когда они используются для этой цели. Моя программа называется PIPE.COM
и он просто вставляет пустое пространство в пустые строки, поэтому все строки могут быть непосредственно обработаны FOR
команда без дальнейших корректировок (пока вставленное пространство не заботится). Вот это:
@ECHO off
if not exist pipe.com call :DefinePipe
FOR /F "USEBACKQ delims=" %%A IN (`pipe ^< "build.properties"`) DO (
ECHO(--%%A--
)
pause
goto :EOF
:DefinePipe
setlocal DisableDelayedExpansion
set pipe=´)€ì!Í!ŠÐŠà€Ä!€ü.t2€ü+u!:æu8²A€ê!´#€ì!Í!².€ê!´#€ì!Í!²+€ê!´#€ì!Í!Šò€Æ!´,€ì!Í!"Àu°´LÍ!ëÒ
setlocal EnableDelayedExpansion
echo !pipe!>pipe.com
exit /B
редактировать: добавление как ответ на новый комментарий
код at: DefinePipe подпрограмма создать программу 88 байт называется pipe.com, что в основном делает процесс, эквивалентный этому псевдо-пакетному коду:
set "space= "
set line=
:nextChar
rem Read just ONE character
set /PC char=
if %char% neq %NewLine% (
rem Join new char to current line
set line=%line%%char%
) else (
rem End of line detected
if defined line (
rem Show current line
echo %line%
set line=
) else (
rem Empty line: change it by one space
echo %space%
)
)
goto nextChar
таким образом, пустые строки во входном файле изменяются строками с одним пробелом, поэтому команда FOR /F больше не опускает их. Это работает "до тех пор, пока вставленное пространство не заботится", как я сказал в своем ответе.
обратите внимание, что pipe.com программа не работает в 64-битных версиях Windows.
Антонио
выходные строки, включая пустые строки
вот метод, который я разработал для собственного использования.
сохраните код в виде пакетного файла, скажем,SHOWALL.Летучая мышь!--11--> и передать исходный файл в качестве параметра командной строки.
выход можно перенаправить или пипед.
@echo off
for /f "tokens=1,* delims=]" %%a in ('find /n /v "" ^< "%~1"') do echo.%%ba
exit /b
примеры:
showall источник.txt
showall источник.txt >назначения.txt
showall источник.txt | найти "строку"
странностью является включение '^' (перенаправление), а не просто делать следующее:
for /f "tokens=1,* delims=]" %%a in ('find /n /v "" "%~1"') do echo.%%ba
опуская перенаправление, выводится ведущая пустая строка.
благодаря dbenham это работает, хотя это немного отличается от его предложения:
::preserve blank lines using FIND, no limitations
for /f "USEBACKQ delims=" %%A in (`type "file.properties" ^| find /V /N ""`) do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*]=!"
echo(!ln!
endlocal
)
как говорится в этой ответ на вышеуказанный вопрос, не кажется, что строки пропускаются по умолчанию с помощью for /f
in (по крайней мере) Windows XP
(сообщество-обновите этот ответ, Протестировав приведенные ниже пакетные команды в вашей версии и пакете обновления Windows
).
EDIT: Per Джеб ' s комментарий ниже кажется, что ping
команда, по крайней мере Windows XP
, is
вызывая for /f
в производить <CR>
вместо пустых строк (Если кто-то знает конкретно почему, будет
оцените, если они могут обновить этот ответ или комментарий).
в качестве обходного пути кажется, что второй маркер с разделителями по умолчанию (<space>
/ %%b
в пример)
возвращается как blank
, который работал для моей ситуации устранения пустых строк с помощью "родителя"
if
условно на втором токене в начале for /f
, как это:
for /f "tokens=1,2*" %%a in ('ping -n 1 google.com') do (
if not "x%%b"=="x" (
{do things with non-blank lines}
)
)
Используя приведенный ниже код:
@echo off
systeminfo | findstr /b /c:"OS Name" /c:"OS Version"
echo.&echo.
ping -n 1 google.com
echo.&echo.
for /f %%a in ('ping -n 1 google.com') do ( echo "%%a" )
echo.&echo.&echo --------------&echo.&echo.
find /?
echo.&echo.
for /f %%a in ('find /?') do ( echo "%%a" )
echo.&echo.
pause
.... ниже приведено то, что я вижу в Windows XP, Windows 7 и Windows 2008, являясь единственными тремя версиями и пакетами обновлений Windows, к которым у меня есть готовый доступ: