Проблема с выводом этой команды FOR

Проблема с выводом этой команды FOR

Я только что понял, что запускаю bat-файл в начале этого раздела реестра, в котором есть echo running abcи некоторые другие не имеющие отношения к делу вещи

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun

Итак, я изменил этот bat-файл. Это всего лишь одна строка, в ней нет ничего несущественного.

вы видите содержимое bat-файла.

Вот некоторые выходные данные из командной строки, показывающие текущую ситуацию, которая является той же фундаментальной проблемой, но вы должны быть в состоянии воспроизвести проблему.

Теперь вопрос в том,

  • Почему написано echo sss, а не echo sss ttt?
  • Как мне подавить запуск cmd или этого файла инициализации bat с помощью FOR? Оператор FOR на самом деле должен просто отображать "echo g", а не "echo sss" или "echo sss ttt".

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
sss ttt
C:\Documents and Settings\Administrator>cd\

C:\>type \blah\startfile.bat <ENTER>
@echo sss ttt   

C:\>  

C:\>for /f %f in ('echo g ^| findstr "g"') do echo %f <ENTER>

C:\>echo sss
sss

C:\>echo g
g

C:\>

решение1

Почему написано echo sss, а не echo sss ttt?

Поскольку строка sss tttсодержит пробел, forкоманда токенизирует ее и сохраняет первую половину sssв переменной %f, а вторую половину tttв %gпеременной.

Как мне подавить запуск cmd или этого файла инициализации bat с помощью FOR? Оператор FOR на самом деле должен просто отображать "echo g", а не "echo sss" или "echo sss ttt".

Похоже, для оценки echo g ^| findstr "g"инициализируется новый интерпретатор команд, а ваш \blah\startfile.batавтоматически выполняется. Сделайте так, чтобы ваш пакет ничего не выводил.

решение2

Если вы собираетесь использовать его %fв пакетном файле, вам нужно экранировать его другим %:

for /f %%f in ('echo g ^| findstr "g"') do echo %%f

Добавьте это в свой пакетный файл, и вы получите желаемый результат.

решение3

Хочу немного расширить ответ Властимила...

КогдаFORкоманда выполняет"echo g"и перенаправляет вывод вfindstr,ДЛЯдолжен сначала запустить новый командный процессор, что вызывает\blah\startfile.batбыть казненным.

\blah\startfile.batвыводит строку, содержащуюsss ttt. Эта строка обрабатываетсяДЛЯи являетсяНЕТпереданоfindstr.

Согласно справке дляДЛЯ:

Обработка состоит из ..., разбиения на отдельные строки текста и последующего разбора каждой строки на ноль или более токенов. Затем вызывается тело цикла for со значением(ями) переменной, установленным на найденную строку(и) токенов. По умолчанию /F передает первый пустой отделенный токен из каждой строки...

Разделители по умолчанию дляДЛЯявляются:" ,;"(пробел, запятая и точка с запятой).

Первая строка, котораяДЛЯпроцессы содержат строку:ссс ттт. Эта строка содержит" "(пробел), который является разделителем по умолчанию дляДЛЯ, который анализирует строку и назначает первую строку токена:"сссс"к"%ф". Итак"эхо %f"выводит строку, содержащую только:"сссс". Это первая строка, которую вы видите напечатанной."ттт"просто отбрасывается, потому что"ДЛЯ ... эхо %f"команда не указала, что необходимо включить что-либо, кроме первого токена.

ЕслиДЛЯкоманда была написана по-другому, вы бы увидели полную строку"ссс ттт"повторил.

Вот 3 способаДЛЯДля этого можно было бы написать команду.

Первый способ, с использованием"delims="опция, устанавливает разделитель дляДЛЯ"пустой", так чтоДЛЯвозвращает всю строку как 1 токен. Токены все еще анализируются, и все разделители (" ,;") удаляются, затем все токены снова объединяются с пробелом между каждым токеном. Это объединенное значение возвращается в переменной"%ф"

C:\>for /f "delims=" %f in ('echo sss ttt')  do echo %f

C:\>echo sss ttt
sss ttt

C:\>for /f "delims=" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f

C:\>echo mm nn oo ss tt
mm nn oo ss tt

Следующий способ, с использованием"tokens=*"вариант, рассказываетДЛЯпоместить все найденные токены в значение указанной переменной ("%ф"). Токены по-прежнему анализируются, и все разделители удаляются, затем все токены снова объединяются с пробелом между каждым токеном.

C:\>for /f "tokens=*" %f in ('echo sss ttt')  do echo %f

C:\>echo sss ttt
sss ttt

C:\>for /f "tokens=*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f

C:\Users\1-kevin>echo mm nn oo ss tt
mm nn oo ss tt

Этот третий способ, с использованием"tokens=1,*"вариант, рассказываетДЛЯпоместить первый (1) найденный токен в значение указанной переменной ("%ф"). Оставшиеся токены анализируются, и все разделители удаляются, затем все оставшиеся токены снова объединяются с пробелом между каждым токеном, и это объединенное значение возвращается в переменной, названной буквой, которая следует за указанным именем переменной (так, в этом случае переменная"%г").

C:\>for /f "tokens=1,*" %f in ('echo sss ttt')  do echo %f %g

C:\>echo sss ttt
sss ttt

C:\>for /f "tokens=1,*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo "%f" "%g"

C:\>echo "mm" "nn oo ss tt"
"mm" "nn oo ss tt"

Обратите внимание, что следующее не будет работать, поскольку для переменных, выходящих за пределы указанной переменной, не определены «токены»"%ф":

C:\>for /f %f in ('echo sss ttt')  do echo %f %g

C:\>echo sss %g
sss %g


Итак, в вашем примере, если вы добавили"delims="вариант, вы увидите это:

C:\>for /f "delims=" %f in ('echo g ^| findstr "g"') do echo %f

C:\>echo sss ttt
sss ttt

C:\>echo g
g

C:\>

Связанный контент