Подтвердить что ты не робот

Пакетная справка Windows при настройке переменной из вывода команды

Мне нужно запустить простую команду find и перенаправить вывод в переменную в пакетном файле Windows.

Я пробовал это:

set file=ls|find ".txt"
echo %file%

Но это не сработает.

Если я запустил эту команду, она работает без проблем:

set file=test.txt
echo %file%  

Поэтому, очевидно, что мой вывод команды не задан для моей переменной. Может ли кто-нибудь помочь? Благодаря

4b9b3361

Ответ 1

Я просто узнаю, как использовать в нем команды с трубами, вот моя команда (которая извлекает головную ревизию svn repo):

SET SVN_INFO_CMD=svn info http://mySvnRepo/MyProjects
FOR /f "tokens=1 delims=" %%i IN ('%SVN_INFO_CMD% ^| find "Revision"') DO echo %%i

Ответ 2

Прежде всего, то, что вы ожидаете от своего вопроса, даже не возможно в оболочках UNIX. Как оболочка должна знать, что ls|find foo является командой, а test.txt - нет? Что здесь выполнить? Вот почему UNIX-оболочки имеют откат для таких вещей. Во всяком случае, я отвлекаюсь.

Вы не можете устанавливать переменные среды в многострочные строки из оболочки. Таким образом, теперь у нас есть проблема, потому что вывод ls не совсем подходит.

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

Если вам просто нужно выполнить действие для каждого текстового файла:

for %%i in (*.txt) do echo Doing something with "%%i"

Это даже работает для имен файлов с пробелами и не будет ошибочно ловить файлы, у которых есть только .txt в середине их имени, например foo.txt.bar. Просто отметим, что ваш подход не так хорош, как вам бы хотелось.

В любом случае, если вам нужен список файлов, вы можете использовать небольшой трюк для создания массивов или что-то в этом роде:

setlocal enabledelayedexpansion
set N=0
for %%i in (*.txt) do (
    set Files[!N!]=%%i
    set /a N+=1
)

После этого у вас будет ряд переменных среды, называемых Files[0], Files[1] и т.д., каждый из которых содержит одно имя файла. Вы можете выполнить цикл с помощью

for /l %%x in (1,1,%N%) do echo.!Files[%%x]!

(Обратите внимание, что здесь мы выводим лишнюю новую строку, мы можем удалить это, но еще одну строку кода: -))

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

setlocal enabledelayedexpansion
set Files=
for %%i in (*.txt) do set Files=!Files! "%%i"

Теперь у нас есть действительно длинная строка с именами файлов. Используйте его так, как хотите. Это иногда удобно для передачи нескольких файлов в другую программу.

Имейте в виду, что максимальная длина строки для пакетных файлов составляет около 8190 символов. Таким образом, это ограничивает количество вещей, которые вы можете иметь в одной строке. И да, перечисление целой группы файлов в одной строке может переполняться здесь.

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

for /f %%i in ('dir /b') do ...

Это приведет к переходу по линиям, возвращаемым командой, и помечает их по пути. Не так удобно, возможно, как backticks, но достаточно близко и достаточно для большинства кукол.

По умолчанию токены разбиваются на пробелы, поэтому, если у вас есть имя файла "Foo bar", тогда у вас будет только "Foo" в %%i и "bar" в %%j. Это может сбивать с толку, и такие вещи являются основной причиной, по которой вы никогда не захотите использовать for /f, чтобы получить список файлов.

Вы также можете использовать backticks вместо apostrophes, если это противоречит некоторым аргументам программы:

for /f "usebackq" %%i in (`echo I can write 'apostrophes'`) do ...

Обратите внимание, что это также токенизирует. Есть еще несколько вариантов, которые вы можете дать. Они подробно описаны в команде help for.

Ответ 3

set команда имеет параметр /p, который сообщает ему, чтобы прочитать значение из стандартного ввода. К сожалению, он не поддерживает подключение к нему, но поддерживает чтение значения из первой строки существующего файла.

Итак, чтобы установить вашу переменную в имя первого файла *.txt, вы можете сделать следующее:

dir /b *.txt > filename.tmp
set /p file=< filename.tmp
del /q filename.tmp

Важно не добавлять пробел до или даже после =.

Р. S. No for s, no tokens.

Ответ 4

Вот командный файл, который вернет последний элемент вывода find:

@echo off

ls | find ".txt" > %temp%\temp.txt
for /f %%i in (%temp%\temp.txt) do set file=%%i
del %temp%\temp.txt
echo %file%

for имеет синтаксис для синтаксического анализа вывода команды, for /f "usebackq", но он не может обрабатывать каналы в команде, поэтому я перенаправил вывод во временное местоположение.

Я настоятельно рекомендую, учитывая, что у вас есть доступ к ls, который вы считаете использующим более эффективный пакетный язык, например bash или даже язык сценариев, например python или ruby. Даже bash будет 20-кратным улучшением по сравнению с cmd-скриптами.

Ответ 5

Короткий ответ: Do not!

Окна env var могут содержать максимум 32 Кбайт, и небезопасно сохранять вывод из программ в них. Вот почему вы не можете. В пакете script вы должны принять другой стиль программирования. Если вам нужен весь вывод из программы, затем сохраните ее в файл. Если вам нужно только проверить определенные свойства, тогда проведите вывод в программа, которая выполняет проверку и использование механизма errorlevel:

@echo off

type somefile.txt | find "somestring" >nul
if %errorlevel% EQU 1 echo Sorry, not found!
REM Alternatively:
if errorlevel 1 echo Sorry, not found!

Однако более элегантно использовать логические операторы Perl-стиля:

@echo off

(type somefile.txt | find "somestring" >nul) || echo Sorry, not found!

Ответ 6

Он недоступен в DOS, но в консоли Windows есть команда for. Просто введите "help for" в командной строке, чтобы просмотреть все параметры. Чтобы установить одну переменную, вы можете использовать это:

for /f %%i in ('find .txt') do set file=%%i

Обратите внимание, что это будет работать только для первой строки, возвращаемой из 'find.txt', потому что окна по умолчанию только расширяют переменную. Вам нужно будет включить отложенное расширение, как показано здесь.

Ответ 7

то, что вы в основном делаете, это перечисление файлов .txt. При этом вы можете использовать цикл for для обработки dir cmd например,

for /f "tokens=*" %%i in ('dir /b *.txt') do set file=%%i

или если вы предпочитаете использовать свои ls, вам не нужно искать трубку.

for /f "tokens=*" %%i in ('ls *.txt') do set file=%%i

Ответ 8

Пример установки переменной из выходного файла команды:

FOR /F "usebackq" %%Z IN ( `C:\cygwin\bin\cygpath "C:\scripts\sample.sh"` ) DO SET BASH_SCRIPT=%%Z

c:\cygwin\bin\bash -c '. ~/.bashrc ; %BASH_SCRIPT%'

Также обратите внимание, что если вы хотите проверить команду FOR в оболочке DOS, вам нужно использовать только% Z вместо %% Z, иначе она будет жаловаться на следующую ошибку:

%%Z was unexpected at this time.