DOS пакетный цикл FOR с FIND.exe удаляет пустые строки?
Этот пакетный скрипт DOS удаляет пустые строки и не показывает пустые строки в файле, хотя я использую команду TYPE.exe для преобразования файла, чтобы убедиться, что файл ASCII, так что команда FIND совместима с файлом , Может ли кто-нибудь сказать мне, как сделать этот скрипт пустым?
@ECHO off FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE.exe "build.properties" ^| FIND.exe /V ""`) DO ( ECHO --%%A-- ) pause
- Как проверить размер файла в пакетном скрипте Windows?
- Как сделать одну конкретную строку командного файла другим цветом, чем другие?
- командный файл: список rar-файла в определенной папке и запись результата в текстовый файл
- Как сохранить результат выражения команды в переменной с помощью битовых скриптов?
- Сравнение пакетных файлов переменной с константой
- Команда Batch для обнаружения всех возможных проблем с ping
- Как удалить конечные и ведущие пробелы для пользовательского ввода в пакетном файле?
- Как разбить имя файла из полного пути в пакетном режиме?
- Как запустить файл «.bat» во время установки?
- Как запустить пакетный скрипт без использования расширения * .bat
- Пакетные файлы Windows: что такое переменное расширение и что означает EnableDelayedExpansion?
- Как вызвать пакетный скрипт из Powershell?
- Файл BATCH запрашивает файл или папку
Это спроектированное поведение FOR / F – оно никогда не возвращает пустые строки. Работа заключается в том, чтобы использовать FIND или FINDSTR для префикса строки с номером строки. Если вы не можете гарантировать, что строки не начинаются с разделителя номера строки, тогда вы просто устанавливаете соответствующий разделитель и сохраняете токены 1 *, но используете только второй токен.
::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 через канал или redirect.
Если файл может содержать строки, начинающиеся с разделителя, вам необходимо сохранить всю строку с префиксом номера строки, а затем использовать поиск и замену, чтобы удалить префикс строки. Вероятно, вы хотите отсрочить расширение при переносе %% 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) строки должны иметь длину <= 1021 байта (без учета
3) любые конечные управляющие символы удаляются из каждой строки.
4) он должен прочитать из файла – вы не можете использовать канал. Поэтому в вашем случае вам нужно будет использовать временный файл для преобразования 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
EDIT : Добавление как ответ на новый комментарий
Код в подпрограмме 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.BAT и передайте исходный файл в качестве параметра командной строки.
Вывод может быть перенаправлен или подключен к сети.
@echo off for /f "tokens=1,* delims=]" %%a in ('find /n /v "" ^< "%~1"') do echo.%%ba exit /b
ПРИМЕРЫ:
showall source.txt
showall source.txt > destination.txt
showall source.txt | НАЙТИ "Строка"
Нечеткость - это включение « ^ < '(redirect), а не просто следующее:
for /f "tokens=1,* delims=]" %%a in ('find /n /v "" "%~1"') do echo.%%ba
Отключив redirect, выводится ведущая пустая строка.
Благодаря 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
в (по крайней мере) Windows XP
(Сообщество – обновите этот ответ, протестировав приведенные ниже командные команды на вашей версии и службе пакет Windows
).
РЕДАКТИРОВАТЬ: Комментарий к Джебу ниже , кажется, что команда ping
, по крайней мере, в Windows XP
,
заставляя for /f
производить
‘вместо пустых строк (если кто-то знает, почему,
оцените, если они могут обновить этот ответ или комментарий).
В качестве обходного пути кажется, что второй дефинированный токен по умолчанию (
/ %%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, у меня есть готовый доступ к: