it-swarm.com.ru

Скрытые возможности пакетных файлов Windows

Каковы некоторые из менее известных, но важных и полезных функций пакетных файлов Windows?

Методические рекомендации:

  • Одна особенность за ответ
  • Дайте краткое описание функции и пример , а не только ссылка на документацию
  • Ограничение ответов на встроенную функциональность , т. Е. Не требует дополнительного программного обеспечения, такого как Windows Resource Kit

Пояснение: мы ссылаемся здесь на сценарии, которые обрабатываются cmd.exe, который является вариантом по умолчанию для вариантов WinNT.

(Смотрите также: Пакетные файлы Windows: .bat против .cmd? )

232
Chris Noe

Продолжение строки:

call C:\WINDOWS\system32\ntbackup.exe ^
    backup ^
    /V:yes ^
    /R:no ^
    /RS:no ^
    /HC:off ^
    /M normal ^
    /L:s ^
    @daily.bks ^
    /F daily.bkf
185
Chris Noe
PUSHD path

Перемещает вас в каталог, указанный путь.

POPD

Возвращает вас в каталог, из которого вы "нажали".

150
raven

Не уверен, насколько это полезно в файле batch, но эту команду очень удобно использовать в командной строке:

C:\some_directory> start .

Это откроет Windows Explorer в папке "some_directory".

Я нашел это очень экономит время.

109
LeopardSkinPillBoxHat

Мне всегда было трудно читать комментарии, помеченные ключевым словом в каждой строке:

REM blah blah blah

Легче читать:

:: blah blah blah
87
Chris Noe

Переменные подстроки:

> set str=0123456789
> echo %str:~0,5%
01234
> echo %str:~-5,5%
56789
> echo %str:~3,-3%
3456
79
Chris Noe

команда FOR ! Хотя я ненавижу писать командные файлы, я благодарен за это.

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

будет анализировать каждую строку в myfile.txt, игнорируя строки, начинающиеся с точки с запятой, передавая 2-й и 3-й токены из каждой строки в тело for, с токенами, разделенными запятыми и/или пробелами. Обратите внимание, что операторы body ссылаются на% i, чтобы получить 2-й токен,% j, чтобы получить 3-й токен, и% k, чтобы получить все оставшиеся токены после 3-го.

Вы также можете использовать это для перебора каталогов, содержимого каталогов и т.д.

72
TheSoftwareJedi

Вместо того, чтобы засорять скрипт с помощью REM или :: строк, я делаю следующее в верхней части каждого скрипта:

@echo OFF
goto :START

Description of the script.

Usage:
   myscript -parm1|parm2 > result.txt

:START

Обратите внимание, как вы можете использовать символы канала и перенаправления, не экранируя их.

60
Patrick Cuff

Путь (с диском), где находится скрипт: ~ dp0

set BAT_HOME=%~dp0
echo %BAT_HOME%
cd %BAT_HOME%
54
RealHowTo

Часть% ~ dp0 уже упоминалась, но на самом деле есть еще кое-что: символы после ~ определяют извлекаемую информацию.
Отсутствие буквы приводит к возврату имени файла патча
d - возвращает букву диска
p - возвращает путь
s - возвращает короткий путь
x - возвращает расширение файла
Таким образом, если вы выполните скрипт test.bat ниже из папки c:\Temp\long dir name \,

@echo off
echo %0
echo %~d0
echo %~p0
echo %~dp0
echo %~x0
echo %~s0
echo %~sp0

вы получите следующий вывод

test
c:
\Temp\long dir name\
c:\Temp\long dir name\
.bat
c:\Temp\LONGDI~1\test.bat
\Temp\LONGDI~1\

И если параметр передается в ваш скрипт, как в
test c:\temp\mysrc\test.cpp
Те же манипуляции можно выполнить с переменной% 1.

Но результат расширения% 0 зависит от местоположения!
На "верхнем уровне" пакета оно расширяется до текущего имени файла пакета.
В функции (вызове) она расширяется до имени функции.

@echo off
echo %0
call :test
goto :eof

:test
echo %0
echo %~0
echo %~n0

Выход (пакетный файл запускается с myBatch.bat)

myBatch.bat
:test
:test
myBatch
49
Hartmut

Используя CALL, EXIT/B, SETLOCAL & ENDLOCAL, вы можете реализовать подпрограммы с локальными переменными.

пример:

@echo off

set x=xxxxx
call :sub 10
echo %x%
exit /b

:sub
setlocal
set /a x=%1 + 1
echo %x%
endlocal
exit /b

Это напечатает

11
xxxxx

хотя: sub изменяет x.

43
Ferruccio

Подлый трюк с ожиданием N секунд (не является частью cmd.exe, но не является дополнительным программным обеспечением, поскольку он поставляется с Windows), см. Строку ping. Вам нужно N + 1 пингов, так как первый пинг проходит без задержки.

    echo %time%
    call :waitfor 5
    echo %time%
    goto :eof
:waitfor
    setlocal
    set /a "t = %1 + 1"
    >nul ping 127.0.0.1 -n %t%
    endlocal
    goto :eof
42
paxdiablo

Спасаясь от "сантехники":

echo ^| ^< ^> ^& ^\ ^^
37
Chris Noe

Возможность запускать команды и обрабатывать вывод (например, обратные пометки '$ ()' в bash).

for /f %i in ('dir /on /b *.jpg') do echo --^> %i

Если в именах файлов есть пробелы, используйте это:

for /f "tokens=*" %i in ('dir /on /b *.jpg') do echo --^> %i
31
paxdiablo

Создание пустого файла:

> copy nul filename.ext
30
nzpcmad

Чтобы скрыть весь вывод команды перенаправить на> nul 2> & 1.

Например, некоторые программы командной строки отображают вывод, даже если вы перенаправляете на> nul. Но если вы перенаправите вывод, как показано ниже, все выходные будут подавлены.

PSKILL NOTEPAD >nul 2>&1

Правка: Смотрите игнорируя вывод команды для объяснения того, как это работает.

28
aphoria

Эквивалент bash (и других оболочек)

echo -n Hello # or
echo Hello\\c

который выводит "Hello" без завершающего символа новой строки. Хак для этого:

<nul set /p any-variable-name=Hello

set /p - это способ предложить пользователю ввести данные. Он выдает заданную строку и затем ждет (на той же строке, то есть CRLF), чтобы пользователь набрал ответ.

<nul просто передает пустой ответ на команду set /p, так что в результате получается строка запроса. (Используемая переменная остается неизменной из-за пустого отклика.)

Проблемы: Невозможно вывести начальный знак равенства, а в Vista начальные пробельные символы удаляются, но не в XP.

25
paxdiablo
PAUSE

Останавливает выполнение и отображает следующую подсказку:

Нажмите любую клавишу для продолжения . , ,.

Полезно, если вы хотите запустить пакет, дважды щелкнув его в проводнике Windows, и хотите увидеть результат, а не просто всплывающее окно командной строки.

25
raven

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

> @set fname=%date:/=%

... удаляет "/" из даты для использования в именах файлов с метками времени.

и подстроки тоже ...

> @set dayofweek=%fname:~0,3%
18
SqlACID

Целочисленная арифметика:

> SET /A result=10/3 + 1
4
17
Chris Noe

Разделители команд:

cls & dir
copy a b && echo Success
copy a b || echo Failure

Во 2-й строке команда после && выполняется только в том случае, если первая команда выполнена успешно.

На 3-й строке команда после || запускается только в случае сбоя первой команды.

16
doekman

Вы можете соединять операторы if для получения эффекта, подобного короткому замыканию логического `and '.

if foo if bar baz
15
Jack

Выведите пустую строку:

echo.
15
paxdiablo

если структура блока:

if "%VS90COMNTOOLS%"=="" (
  echo: Visual Studio 2008 is not installed
  exit /b
)
14
Ferruccio

Для быстрого преобразования текстового файла Unicode (16 бит/символ) в файл DOS ASCII (8 бит/символ).

C:\> type unicodeencoded.txt > dosencoded.txt

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

14
RealHowTo

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

@title Searching for ...
:: processing search
@title preparing search results
:: data processing
12
Hartmut

Задержка раскрытия переменных (с подстроками, добавленными для хорошей меры):

    @echo off
    setlocal enableextensions enabledelayedexpansion
    set full=/u01/users/pax
:loop1
    if not "!full:~-1!" == "/" (
        set full2=!full:~-1!!full2!
        set full=!full:~,-1!
        goto :loop1
    )
    echo !full!
    endlocal
12
paxdiablo

У вас нет удобного редактора, и вам нужно создать командный файл?

copy con test.bat

Просто введите команды, нажмите ввод для новой строки. Нажмите Ctrl-Z и Enter, чтобы закрыть файл.

11
Hartmut

пример вычитания строки в date и time для получения файла с именем "YYYY-MM-DD HH: MM: SS.txt"

echo test > "%date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,2%_%time:~3,2%_%time:~6,2%.txt"

Я использую color, чтобы указать, если мой сценарий завершится успешно, потерпел неудачу или нуждается в некотором вводе, меняя цвет текста и фона. Это действительно помогает, когда у вас есть машина в пределах досягаемости, но довольно далеко

цвет XY

где X и Y - шестнадцатеричное значение от 0 до F, где X - фон, Y - текст, когда X = Y цвет не изменится.

цвет Z

меняет цвет текста на "Z" и устанавливает черный фон, "цвет 0" не будет работать

для названий цветов звоните

цвет ?

11
MoreThanChaos

Полный контроль над выводом с пробелами и escape-символами .:

echo.    ^<resourceDir^>/%basedir%/resources^</resourceDir^>
10
paxdiablo

TheSoftwareJedi уже упомянул команду for, но я собираюсь упомянуть ее еще раз, поскольку она очень мощная.

Ниже выводится текущая дата в формате ГГГГММДД, я использую ее при создании каталогов для резервных копий.

for /f "tokens=2-4 delims=/- " %a in ('DATE/T') do echo %c%b%a
9
remonedo

Вы можете использовать call для оценки имен позже, что приведет к некоторым полезным свойствам.

call set SomeEnvVariable_%extension%=%%%somevalue%%%

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

call set TempVar=%%SomeEnvVariable_%extension%%%

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

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

setlocal EnableDelayedExpansion
8
Lara Dougan

Поиск исполняемого файла по пути (или другой похожей на путь строке, если необходимо):

c:\> for %i in (cmd.exe) do @echo. %~$PATH:i
C:\WINDOWS\system32\cmd.exe

c:\> for %i in (python.exe) do @echo. %~$PATH:i
C:\Python25\python.exe

c:\>
7
paxdiablo

Что касается использования :: вместо REM для комментариев: будьте осторожны! :: - это особый случай метки CALL, которая действует как комментарий. При использовании внутри скобок, например, в цикле FOR или IF, функция преждевременно завершает работу. Очень расстраивает отладку!

Смотрите http://www.ss64.com/nt/rem.html для полного описания.

(добавление в качестве нового ответа вместо комментария к первое упоминание об этом выше потому что я еще не заслуживаю упоминания: 0)

7
matt wilkie

Локальные переменные все еще анализируются для строки, которую использует ENDLOCAL. Это учитывает уловки как:

ENDLOCAL & SET MYGLOBAL=%SOMELOCAL% & SET MYOTHERGLOBAL=%SOMEOTHERLOCAL%

Это полезный способ передачи результатов в вызывающий контекст. В частности,% SOMELOCAL% выходит из области действия, как только ENDLOCAL завершает работу, но к тому времени% SOMELOCAL% уже раскрывается, поэтому MYGLOBAL назначается в контексте вызова с локальной переменной.

По той же причине, если вы решили сделать:

ENDLOCAL & SET MYLOCAL=%MYLOCAL%

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

6
Coding With Style

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

Преимущество использования EXIT/B состоит в том, что вы можете добавить уровень ошибки после EXIT/B, и он выйдет с этим уровнем ошибки.

6
Coding With Style

Режим быстрого редактирования в cmd.exe - мой любимый. Это немного не по теме, но при взаимодействии с командой Shell это может быть спасением. Нет, я не гиперболичен - вы увидите только caret-capitol-v определенное количество раз, прежде чем умрете; чем больше ты видишь, тем быстрее ты умрешь.

  1. Откройте regedit (осторожно, не моя вина, синий экран и т.д.)
  2. Перейти к HKCU/Консоль
  3. Установите QuickEdit на 1

(Вы также можете установить это с помощью пользовательского интерфейса, что, вероятно, является лучшим способом. См. Комментарии для получения инструкций. Также есть хороший однострочный скрипт для этого.)

Теперь, чтобы скопировать, просто щелкните левой кнопкой мыши и перетащите, чтобы выбрать, и щелкните правой кнопкой мыши, чтобы скопировать. Чтобы вставить, просто щелкните правой кнопкой мыши.

НЕТ БОЛЬШЕ ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V !!!

, я думаю, что просто кого-то убил. Сожалею!

5
Will

Call Set - расширяет переменные окружения на несколько уровней.

Нашел это по адресу http://ss64.com/nt/call.html#advanced из ответа на другой вопрос SO переменные пакетного файла инициализированы в цикле for

set VarName=Param
set Param=This

call set Answer=%%%Varname%%%
Echo %Answer%

дает

set VarName=Param
set Param=This
call set Answer=%Param%
Echo This
This
5
Andy Morris

Подпрограммы (выходы 42):

    @echo off
    call :answer 42
    goto :eof
:do_something
    echo %1
    goto :eof

и подпрограммы, возвращающие значение (выходные данные 0, 1, 2 и т. д.):

    @echo off
    setlocal enableextensions enabledelayedexpansion
    call :seq_init seq1
:loop1
    if not %seq1%== 10 (
        call :seq_next seq1
        echo !seq1!
        goto :loop1
    )
    endlocal
    goto :eof

:seq_init
    set /a "%1 = -1"
    goto :eof
:seq_next
    set /a "seq_next_tmp1 = %1"
    set /a "%1 = %seq_next_tmp1% + 1"
    set seq_next_tmp1=
    goto :eof
5
paxdiablo

Опция подкаталога "удалить каталог":

rd /s /q junk
4
paxdiablo

Перенаправление вывода на консоль, даже если вывод пакета уже перенаправлен в файл с помощью синтаксиса > con.

Пример: foo.cmd:

echo a
echo b > con

Вызов:

foo.cmd > output.txt

Это приведет к тому, что "a" перейдет к output.txt, а "b" пойдет на консоль.

4
NicJ
SHIFT

Это способ перебора переменного количества аргументов, передаваемых в сценарий (или подпрограмму) в командной строке. В простейшем случае он смещает% 2 на% 1,% 3 на% 2 и т.д. (Вы также можете передать параметр в SHIFT, чтобы пропустить несколько аргументов.) Это делает команду "деструктивной" (т. Е.% 1 исчезает навсегда), но позволяет избежать жесткого кодирования максимального количества поддерживаемых аргументов.

Вот краткий пример обработки аргументов командной строки по одному:

:ParseArgs

if "%1"=="" (
    goto :DoneParsingArgs
)

rem ... do something with %1 ...

shift

goto :ParseArgs


:DoneParsingArgs

rem ...
4
reuben

Вы можете использовать уровень ошибки, чтобы проверить, доступна ли данная программа в системе (текущий каталог или путь), где будет запускаться ваш пакетный файл. Чтобы это работало, программа, которую вы тестируете, должна быть запущена, завершена и установить код выхода, когда это произойдет. В примере я использую -? как аргумент для myExe, большинство программ CLI имеют похожий аргумент, такой как -h, --help, -v и т. д. ... это гарантирует, что он просто запускается и выходит, оставляя или устанавливая уровень ошибки 0

myExe -? >nul 2>&1 
Set errCode=%errorlevel%
@if %errCode% EQU 0 (
    echo myExe -? does not return an error (exists)
) ELSE (
    echo myExe -? returns an error (does not exist)
)

Да, вы можете проверить уровень ошибки напрямую, а не присваивать его errCode, но таким образом вы можете иметь команды между тестом и условием, и вы будете проверять условие повторно при необходимости.

4
batch fool

Получить текущий день, месяц и год (независимо от локали):

for /f "tokens=1-4 delims=/-. " %%i in ('date /t') do (call :set_date %%i %%j %%k %%l)
goto :end_set_date

:set_date
if ("%1:~0,1%" gtr "9") shift
for /f "skip=1 tokens=2-4 delims=(-)" %%m in ('echo,^|date') do (set %%m=%1&set %%n=%2&set %%o=%3)
goto :eof

:end_set_date

echo day in 'DD' format is %dd%; month in 'MM' format is %mm%; year in 'YYYY' format is %yy%
3
Andrei Coșcodan

правильный формат для циклов с числовыми переменными

for /l %%i in (startNumber, counter, endNumber) do echo %%i

подробнее> http://www.ss64.com/nt/for.html

3
Alin Sfetcu

Команда CHOICE запрашивает у пользователя один из нескольких вариантов (нажатием одной клавиши)

@echo off
echo Please choose one of the following options
echo 1. Apple
echo 2. Orange
echo 3. Pizza
echo a, b, c. Something else
choice /c:123abc /m "Answer?"
set ChoiceLevel=%ErrorLevel%
echo Choice was: %ChoiceLevel%

%ChoiceLevel% будет выбранной n-й опцией (в приведенном выше примере b=5).

Более подробная информация на ВЫБОР справочной странице SS64.com .

3
NicJ

Удобный трюк, когда вы хотите скопировать файлы между ветками:

C:\src\branch1\mydir\mydir2\mydir3\mydir4>xcopy %cd:branch1=branch2%\foo*
Overwrite C:\src\branch1\mydir\mydir2\mydir3\mydir4\foo.txt (Yes/No/All)? y
C:\src\branch2\mydir\mydir2\mydir3\mydir4\foo.txt

При этом используется как переменная среды% cd%, так и подстановка переменных среды.

3
Igor Dvorkin

Для синтаксического анализа stdin внутри скрипта вам понадобится этот трюк с командами FOR и FIND:

for /f "tokens=*" %%g in ('find /V ""') do (
     :: do what you want with %%g
     echo %%g
)
3
Philibert Perusse

Массивы в пакетных файлах.

Установите значение:

set count=1
set var%count%=42

Извлеките значение в командной строке:

call echo %var%count%%

Извлеките значение в пакетном файле:

call echo %%var%count%%%

Обратите внимание на дополнительные знаки%.

Техника может выглядеть немного волосатой, но она весьма полезна. Выше будет напечатано содержимое var1 (т.е. 42), как мы объяснили. Мы также можем заменить команду echo на set, если мы хотим установить другую переменную в значение var1 . Это означает, что следующее является допустимым назначением в командной строке:

call set x=%var%count%%

Затем, чтобы увидеть значение va1 :

echo %x%
2
Ben Burnett

/ с Параметр для самого cmd.exe, говорит ему, чтобы он запустился и затем выполнил эти команды.

Раньше я часто делал:

победа + гcMD ВЕРНУТЬ, пинг google.com ВЕРНУТЬ

но сейчас я просто делаю:

победа + гcmd/c ping google.com ВЕРНУТЬ

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

Правка:/ к Работает так же, но оставляет подсказку открытой. Это может пригодиться чаще.

2
Dean Rather

forfiles очень полезен, например, для рекурсивного удаления всех файлов старше двух дней

forfiles /D -2 /P "C:\Temp" /S /C "cmd /c del @path"
2
Brecht Yperman

Что бы это ни стоило, это - неплохой онлайн-справочник по Windows CMD или пакетным файлам. Я узнал несколько вещей, которые я не знал из этого.

2
ConcernedOfTunbridgeWells

Доски Макрос.

Я давно потерял ссылку на это, но я все еще думаю, что это хорошая идея, и стоит поделиться.

Мы можем объединить пакетные файлы и скрипты doskey в один файл. Это может показаться слишком умным, но это работает.

;= @echo off
;= rem Call DOSKEY and use this file as the macrofile
;= %SystemRoot%\system32\doskey /listsize=1000 /macrofile=%0%
;= rem In batch mode, jump to the end of the file
;= goto end

;= Doskey aliases
h=doskey /history

;= File listing enhancements
ls=dir /x $*

;= Directory navigation
up=cd ..
pd=pushd

;= :end
;= rem ******************************************************************
;= rem * EOF - Don't remove the following line.  It clears out the ';' 
;= rem * macro. Were using it because there is no support for comments
;= rem * in a DOSKEY macro file.
;= rem ******************************************************************
;=

Он работает путем определения поддельного макроса doskey ';' который изящно (или тихо) игнорируется, когда он интерпретируется как пакетный файл.

Я сократил версию, указанную здесь, если вы хотите больше, перейдите здесь .

2
Ben Burnett

Использование pushd к пути UNC создаст временное сопоставление диска (начиная с Z и переместившись назад, чтобы найти следующую доступную букву) и поместит вас в этот диск и путь. Когда вы попадаете или выходите из командной строки, временное сопоставление исчезает.

   C:\>pushd \\yourmom\jukebox

   Z:\>pushd \\yourmom\business

   Y:\>

Кроме того, не столько совет по пакетам, сколько совет по среде командной строки, но когда вы работаете в командной строке с pushd и popd и сетевыми ресурсами, полезно модифицировать ваш Prompt с помощью $ + (глубина показа pushd стека) и $ M (показать путь к сетевому ресурсу).

   C:\utils>Prompt $+$m$p$g

   C:\utils>pushd m:

   +\\yourmom\pub M:\>pushd c:\

   ++c:\>pushd
   M:\
   C:\utils  

   ++c:\>popd

   +\\yourmom\pub M:\>popd

   C:\utils>
2
thatbrentguy

Я считаю, что простота, с которой вы можете перенаправить вывод команд в файлы, чрезвычайно полезна:

DIR *.txt > tmp.txt
DIR *.exe >> tmp.txt

Одиночная стрелка создает или перезаписывает файл, к нему добавляется двойная стрелка. Теперь я могу открыть tmp.txt в моем текстовом редакторе и делать разные полезные вещи.

2
raven

Findstr с поддержкой регулярных выражений:

findstr "^[0-9].*" c:\windows\system32\drivers\etc\hosts
2
BartekB

Найти строки в файлах в папке с помощью канала '|' команда:

dir /b *.* | findstr /f:/ "thepattern"
2
Frans Bouma

Встроенные комментарии, используя &::.

:: This is my batch file which does stuff.
copy thisstuff thatstuff  &:: We need to make a backup in case we screw up!

:: ... do lots of other stuff

Как это работает? Это безобразный хак. & - это разделитель команд, приблизительно аппроксимирующий ; оболочек UNIX. :: - это еще один уродливый хак, который своего рода подражает эмуляции оператора REM. Конечный результат заключается в том, что вы выполняете свою команду, а затем выполняете команду "ничего не делать", что приближает комментарий.

Это работает не во всех ситуациях, но работает достаточно часто, чтобы быть полезным хаком.

2
JUST MY correct OPINION

Список всех дисков:

fsutil fsinfo drives
1
Andrei Coșcodan

Установка переменных среды из файла с помощью SET /P

SET /P SVNVERSION=<ver.tmp
1
Anton Tykhyy

Позволяет изменять каталог на основе переменной среды без указания директивы '%'. Если указанная переменная не существует, попробуйте имя каталога.

@if defined %1 (call cd "%%%1%%") else (call cd %1)
1
Paul Hobbs

Добавить файлы используя copy:

copy file1.txt+file2.txt+file3.txt append.txt

Также, чтобы установить все параметры CLI в одну переменную:

SET MSG=%*

Это займет каждое слово (или символ), разделенные пробелами, и сохранит его в одну переменную пакетного файла. Технически, каждый параметр - это% 1,% 2, $ 3 и т.д., Но эта команда SET использует подстановочный знак для ссылки на каждый параметр в stdin.

Пакетный файл:

@SET MSG=%*
@echo %MSG%

Командная строка:

C:\test>test.bat Hello World!
Hello World!
1
DaWolfman

Создать и начать редактирование нового файла

copy con new.txt
This is the contents of my file
^Z

Ctrl + Z отправляет символ ASCII EOF. Это как heredocs в bash:

cat <<EOF > new.txt
This is the contents of my file
EOF
1
dave1010

Символические ссылки:

mklink /d directorylink ..\realdirectory
mklink filelink realfile

Эта команда является родной для Windows Server 2008 и более поздних версий, включая Vista и Windows 7. (Она также включена в некоторые наборы ресурсов Windows).

1
Soulman

Рекурсивно искать строку в дереве каталогов:

findstr /S /C:"string literal" *.*

Вы также можете использовать регулярные выражения:

findstr /S /R "^ERROR" *.log

Рекурсивный поиск файлов:

dir /S myfile.txt
1
bneal

Goto: eof картон

Я добавляю "goto: eof" в конец моих скриптов как удобное место для фрагментов кода. Таким образом, я могу быстро скопировать/вставить в эту область и из нее, без необходимости комментировать/раскомментировать.

goto :eof
:: code scraps
call this.bat
call that.bat
set TS=%DATE:~10%%DATE:~4,2%%DATE:~7,2%-%TIME:~0,2%%TIME:~3,2%%TIME:~6%%
for /R C:\temp\ %%G in (*.bak) DO del %%G
1
Chris Noe

Залог по ошибке.

IF "%errorlevel%" NEQ "0" (
   echo "ERROR:  Something broke.  Bailing out."
   exit /B 1
)
1
caseyboardman

Как и выше, используя CALL, EXIT/B, SETLOCAL & ENDLOCAL, вы можете реализовать функции с локальными переменными и возвращаемыми значениями.

пример:

@echo off

set x=xxxxx
call :fun 10
echo "%x%"
echo "%y%"
exit /b

:fun
setlocal
set /a y=%1 + 1
endlocal & set x=%y%
exit /b

Это напечатает:

"11"
""

Переменная y никогда не покидает локальную область, но из-за того, как CMD разрешает одну строку за раз, вы можете извлечь значение в переменную x в родительской области.

1
MadKat

Несколько команд в одной строке, полезно во многих ситуациях:

& Используется для объединения двух команд, выполняет command1, а затем command2
&& Условная комбинация, выполняет команду2, если команда1 завершается успешно
¦¦ Команда2 выполняется, только если команда1 не выполнена успешно.

Примеры:

:: ** Edit the most recent .TXT file and exit, useful in a .CMD / .BAT **
FOR /F %%I IN ('DIR *.TXT /B /O:-N') DO NOTEPAD %%I & EXIT


:: ** If exist any .TXT file, display the list in NOTEPAD, if not it 
:: ** exits without any error (note the && and the 2> error redirection)
DIR *.TXT > TXT.LST 2> NUL && NOTEPAD TXT.LST
1
PabloG

Метод для установки уровня ошибки на любое желаемое число:

Номер выхода CMD/C
1
Coding With Style

Скрыть ввод для интерактивного пакетного сценария:

  @echo off

  echo hP1X500P[PZBBBfh#b##[email protected]`$fPf]f3/f1/5++u5>in.com

  set /p secret_password="Enter password:"<nul

  for /f "tokens=*" %%i in ('in.com') do (set secret_password=%%i)

  del in.com
1
Andrei Coșcodan

Я бы сказал, что DEBUG.EXE - ОЧЕНЬ полезная и ОЧЕНЬ недоиспользуемая функция пакетных файлов.

Команда DEBUG позволяет вам ...

  1. Собрать и разобрать 16-битный код
  2. Чтение/запись памяти (Современная защищенная память делает это значительно менее полезным.)
  3. Чтение секторов данных с жесткого диска в сыром виде
  4. Hex Edit

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

ПРИМЕЧАНИЕ. Microsoft удалила эту команду из 64-разрядных версий Windows Xp и Vista и намерена полностью удалить ее из Windows 7 из того, что я слышал.

1
Coding With Style

Удалить окружающие цитаты.

for /f "useback tokens=*" %%a in ('%str%') do set str=%%~a

Мне недавно пришлось написать командный файл, который вызывается событием prebuild VS, и я хочу передать в каталог проекта в качестве параметра. В командном файле мне нужно объединить путь с именем вложенной подпапки, но сначала нужно удалить окружающую кавычку.

1
Fadrian Sudaman

Вот как построить CLASSPATH путем сканирования данного каталога.

setlocal ENABLEDELAYEDEXPANSION
if defined CLASSPATH (set CLASSPATH=%CLASSPATH%;.) else (set CLASSPATH=.)
FOR /R .\lib %%G IN (*.jar) DO set CLASSPATH=!CLASSPATH!;%%G
Echo The Classpath definition is %CLASSPATH%

работает в XP (или лучше). В W2K вам нужно использовать пару файлов BAT для достижения того же результата (см. Включить все файлы jar в определение classpath ).

Это не нужно для 1.6, так как вы можете указать подстановочный знак непосредственно в CLASSPATH (например, -cp ".\Lib *").

1
RealHowTo
HELP

При работе с другой версией ОС важно знать, какие команды доступны изначально. Ввод HELP в командной строке показывает, какие команды доступны, с кратким описанием того, что они делают.

cmd.exe /? 

Это перечислит все параметры командной строки для запуска командной строки, а также настройки реестра, которые изменяют поведение всей системы.

0
Mark Arnott

Для циклов с числовыми счетчиками (выходы с 1 по 10):

for /l %i in (1,1,10) do echo %i
0
paxdiablo

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

смотрите Изменение командного файла при его запуске

Я лично думаю об этом больше как о гоче, чем как о особенности.

0
Mashmagar

Этот пакетный файл работает оба с простыми файлы, а также каталоги в качестве параметров командной строки (вы можете смешивать их в любом порядке). Цикл запускает команду (в данном примере 'echo') для любого указанного файла, если параметр является каталогом, он запускает команду рекурсивно для каждого файла в нем.

@echo off
for /f "delims=" %%f in ('dir %* /a-d /b /s') do echo %%f
0
Sascha

Чтобы получить текущую дату/время для файлов журналов и т.д., Я использую это в своих пакетных файлах:

for /f "usebackq tokens=1,2,3,4,5,6,7 delims=/:. " %%a in (`echo %DATE% %TIME%`) do set NOW=%%d%%b%%c_%%e%%f%%g
set LOG=output_%NOW%.log
0
jftuga

Команда IF! Без этого мой пакетный файл был хламом!

@echo off
IF exist %windir%\system32\iexplore.exe goto end

echo Hmm... it seems you do not have Internet Explorer.
echo Great! You seem to understand ;)

:end
echo Hmm... You have Internet Explorer.
echo That is bad :)
0
Deniz Zoeteman

FIND как замена для grep.
Я взломал небольшую "телефонную книгу" для себя с помощью find. Очень полезно:

@echo off
:begin
set /p term=Enter query: 
type phonebookfile.txt |find /i "%term%"
if %errorlevel% == 0 GOTO :choose
echo No entry found
set /p new_entry=Add new entry: 
echo %new_entry% >> phonebookfile.txt 
:choose
set /p action=(q)uit, (n)ew query or (e)dit? [q] 
if "%action%"=="n" GOTO anfang
if "%action%"=="e" (
    notepad phonebookfile.txt
    goto :choose
)

Очень быстро и эффективно.

0
guerda

Линейное исполнение

Хотя в большинстве случаев это неочевидное преимущество, оно может помочь при попытке обновить объекты во время их работы. Например:

UpdateSource.bat

copy UpdateSource.bat Current.bat
echo "Hi!"

Current.bat

copy UpdateSource.bat Current.bat

Теперь выполнение Current.bat производит этот вывод.

HI!

Осторожно хотя пакетное выполнение продолжается по номеру строки. Такое обновление может привести к пропуску или перемещению назад строки, если основные строки не имеют точно одинаковые номера строк.

0
John Fisher

При использовании расширений команд параметров оболочки в сценарии НАСТОЯТЕЛЬНО рекомендуется выполнить следующий прием в начале сценариев.

- Информация вставлена ​​из http://www.ss64.com/nt/setlocal.html

SETLOCAL установит ОШИБКУ, если дан аргумент. Он будет равен нулю, если указан один из двух допустимых аргументов, а один - в противном случае.

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

VERIFY errors 2>nul
SETLOCAL ENABLEEXTENSIONS
IF ERRORLEVEL 1 echo Unable to enable extensions

Это работает, потому что "VERIFY errors" устанавливает ERRORLEVEL в 1, а затем SETLOCAL не сможет сбросить значение ERRORLEVEL, если расширения недоступны (например, если скрипт выполняется под command.com)

Если расширения команд постоянно отключены, SETLOCAL ENABLEEXTENSIONS не восстановят их.

0
Philibert Perusse

Мне очень нравится эта ссылка Windows XP Commands , а также ссылка Синтаксис вверху; он охватывает многие советы и хитрости, уже найденные в других ответах.

0
leander

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

TYPE %1
TYPE %2
TYPE %3
TYPE %4
TYPE %5
...etc

но это становится очень грязным, когда вы хотите проверить, существует ли каждый параметр:

if [%1] NEQ [] (
TYPE %1
)
if [%2] NEQ [] (
TYPE %2
)
if [%3] NEQ [] (
TYPE %3
)
if [%4] NEQ [] (
TYPE %4
)
if [%5] NEQ [] (
TYPE %5
)
...etc

Кроме того, вы можете принять только ограниченное количество параметров с этим подходом.

Вместо этого попробуйте использовать команду SHIFT:

:loop
IF [%1] NEQ [] (
TYPE %1
) ELSE (
GOTO end
)
SHIFT
GOTO loop
:end

SHIFT переместит все параметры на один, поэтому% 2 становится% 1, а% 3 становится% 2 и т.д.

0
sahmeepee

Я использую их как быстрые ссылки на часто используемые каталоги. Пример файла с именем "sandbox.bat", который находится в каталоге в моем PATH

Explorer "C:\Documents and Settings\myusername\Desktop\sandbox"

Вызов сценария просто WIN + R -> песочница

0
jon_brockman

Очень старый (около 1990 г.) прием для получения общего размера переменных среды:

set > test
dir test
del test
0
some

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

:CODELINE
NANT.EXE -buildfile:alltargets.build -l:build.log build.product
@pause
GOTO :CODELINE

Что произойдет, так это то, что после того, как ваше решение завершит сборку, оно будет приостановлено. И затем, если вы нажмете любую клавишу, он снова запустит скрипт сборки. Очень удобно, должен сказать.

0
RWendi

Также есть команда EDLIN. Хотя это может быть старый инструмент-ублюдок, когда-то использовавшийся для линейного редактирования текста, тот факт, что его можно контролировать из командной строки, делает его довольно полезным для пакетного скриптинга, главным образом потому, что, как и в любом другом случае, когда вы используете EDLIN, он единственный доступный инструмент. В конце концов, EDLIN - это не тот инструмент, который вы обычно хотели бы использовать для редактирования текста, если только вы не мазохист. Цитирую Тима Паттерсона (человека, который это написал): "Я был в ужасе, когда узнал, что IBM использует его, а не выбрасывает в окно".

ПРИМЕЧАНИЕ. EDLIN добавляет устаревшие маркеры EOF (1A) в редактируемые файлы. Если вам нужно удалить их, вам, вероятно, придется использовать DEBUG.

0
Coding With Style