あまり知られていないが重要で便利な Windows バッチ ファイルの機能は何ですか?
ガイドライン:
- 回答ごとに 1 つの機能
- ドキュメントへのリンクだけでなく、機能の簡単な説明と例の両方を提供してください
- ネイティブ機能への回答を制限します。つまり、Windows リソース キットのような追加のソフトウェアは必要ありません。
明確化: ここでは、WinNT バリアントのデフォルトである cmd.exe によって処理されるスクリプトを参照します。
あまり知られていないが重要で便利な Windows バッチ ファイルの機能は何ですか?
ガイドライン:
明確化: ここでは、WinNT バリアントのデフォルトである cmd.exe によって処理されるスクリプトを参照します。
行継続:
call C:\WINDOWS\system32\ntbackup.exe ^
backup ^
/V:yes ^
/R:no ^
/RS:no ^
/HC:off ^
/M normal ^
/L:s ^
@daily.bks ^
/F daily.bkf
PUSHD path
pathで指定されたディレクトリに移動します。
POPD
「プッシュ」したディレクトリに戻ります。
これがバッチファイルでどれほど役立つかはわかりませんが、コマンド プロンプトで使用すると非常に便利なコマンドです。
C:\some_directory> start .
これにより、「some_directory」フォルダーで Windows エクスプローラーが開きます。
これは非常に時間の節約になることがわかりました。
私はいつも、各行にキーワードでマークされたコメントを読むのが難しいと感じています:
REM blah blah blah
読みやすい:
:: blah blah blah
可変部分文字列:
> set str=0123456789
> echo %str:~0,5%
01234
> echo %str:~-5,5%
56789
> echo %str:~3,-3%
3456
FOR コマンド! バッチ ファイルを書くのは嫌いですが、感謝しています。
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k
myfile.txt の各行を解析し、セミコロンで始まる行を無視し、各行の 2 番目と 3 番目のトークンを for 本文に渡します。トークンはコンマやスペースで区切られます。for body ステートメントが %i を参照して 2 番目のトークンを取得し、%j を参照して 3 番目のトークンを取得し、%k を参照して 3 番目以降の残りのすべてのトークンを取得することに注意してください。
これを使用して、ディレクトリ、ディレクトリの内容などを反復処理することもできます...
スクリプトに REM や :: 行を散らかすのではなく、各スクリプトの先頭で次のことを行います。
@echo OFF
goto :START
Description of the script.
Usage:
myscript -parm1|parm2 > result.txt
:START
パイプ文字とリダイレクト文字をエスケープせずに使用する方法に注意してください。
スクリプトがあるパス (ドライブ付き): ~dp0
set BAT_HOME=%~dp0
echo %BAT_HOME%
cd %BAT_HOME%
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 を変更しますが。
N 秒間待機する卑劣なトリック (cmd.exe の一部ではありませんが、Windows に付属しているため追加のソフトウェアではありません)。ping 行を参照してください。最初の ping は遅延なく発信されるため、N+1 ping が必要です。
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
「配管」からの脱出:
echo ^| ^< ^> ^& ^\ ^^
コマンドを実行して出力を処理できること (bash の「$()」のバッククォートなど)。
for /f %i in ('dir /on /b *.jpg') do echo --^> %i
ファイル名にスペースが含まれている場合は、これを使用します。
for /f "tokens=*" %i in ('dir /on /b *.jpg') do echo --^> %i
空のファイルの作成:
> copy nul filename.ext
コマンドからのすべての出力を非表示にするには、>nul 2>&1 にリダイレクトします。
たとえば、一部のコマンド ライン プログラムでは、>nul にリダイレクトしても出力が表示されます。ただし、以下の行のように出力をリダイレクトすると、すべての出力が抑制されます。
PSKILL NOTEPAD >nul 2>&1
EDIT:これがどのように機能するかの説明については、コマンドの出力を無視するを参照してください。
bash(および他のシェル)に相当します
echo -n Hello # or
echo Hello\\c
Hello
これは、末尾の改行なしで「」を出力します。これを行うためのcmdハック:
<nul set /p any-variable-name=Hello
set /p
ユーザーに入力を求める方法です。指定された文字列を発行し、ユーザーが応答を入力するのを(同じ行で、つまりCRLFなしで)待機します。
<nul
空の応答をset /p
コマンドにパイプするだけなので、最終的な結果は出力されたプロンプト文字列になります。(応答が空であるため、使用される変数は変更されません。)
問題は次のとおりです。先頭の等号を出力できず、Vistaでは先頭の空白文字が削除されますが、XPでは削除されません。
PAUSE
実行を停止し、次のプロンプトを表示します。
何かキーを押すと続行します 。. .
Windows エクスプローラーでダブルクリックしてバッチを実行し、コマンド ウィンドウのフラッシュだけでなく、実際に出力を確認したい場合に便利です。
環境変数を設定するときの検索と置換:
> @set fname=%date:/=%
...タイムスタンプ付きファイル名で使用する日付から「/」を削除します。
部分文字列も...
> @set dayofweek=%fname:~0,3%
整数演算:
> SET /A result=10/3 + 1
4
コマンドセパレータ:
cls & dir
copy a b && echo Success
copy a b || echo Failure
2行目では、&&の後のコマンドは、最初のコマンドが成功した場合にのみ実行されます。
3行目、||の後のコマンド 最初のコマンドが失敗した場合にのみ実行されます。
空白行を出力します。
echo.
ifステートメントを連鎖させて、ブール値の「and」を短絡するような効果を得ることができます。
if foo if bar baz
Unicode テキスト ファイル (16 ビット/文字) を ASCII DOS ファイル (8 ビット/文字) にすばやく変換します。
C:\> type unicodeencoded.txt > dosencoded.txt
おまけとして、可能であれば、キャラクターは正しくマッピングされます。
if ブロック構造:
if "%VS90COMNTOOLS%"=="" (
echo: Visual Studio 2008 is not installed
exit /b
)
変数の遅延展開 (適切な測定のために部分文字列がスローされます):
@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
多くの機能を提供するわけではありませんが、タイトル コマンドをいくつかの用途に使用できます。たとえば、タスク バーに長いスクリプトのステータスを表示したり、ユーザー フィードバックを強化したりすることができます。
@title Searching for ...
:: processing search
@title preparing search results
:: data processing
「YYYY-MM-DDHH:MM:SS.txt」という名前のファイルを取得するためdate
の文字列減算の例time
echo test > "%date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,2%_%time:~3,2%_%time:~6,2%.txt"
color
テキストと背景の色を変更して、スクリプトが正常に終了したか、失敗したか、または入力が必要かどうかを示すために使用します。あなたがあなたの視界の手の届くところにあるがかなり遠くにある機械を持っているとき、それは本当に役に立ちます
色XY
0
ここで、XとYはからまでの16進値ですF
。ここで、X-背景、Y-テキスト、X=Yの色は変更されません。
カラーZ
テキストの色を「Z」に変更し、背景を黒に設定します。「色0」は機能しません
色の名前については
色 ?
便利なエディターがなく、バッチ ファイルを作成する必要がありますか?
copy con test.bat
コマンドを入力するだけで、Enter キーを押して改行します。Ctrl-Z と Enter を押してファイルを閉じます。
スペースとエスケープ文字を使用して出力を完全に制御します。:
echo. ^<resourceDir^>/%basedir%/resources^</resourceDir^>
TheSoftwareJedi はすでに for コマンドについて言及しましたが、非常に強力なのでもう一度言及します。
以下は、現在の日付を YYYYMMDD の形式で出力します。これは、バックアップ用のディレクトリを生成するときに使用します。
for /f "tokens=2-4 delims=/- " %a in ('DATE/T') do echo %c%b%a
call を使用して後で名前を評価し、いくつかの有用なプロパティに導くことができます。
call set SomeEnvVariable_%extension%=%%%somevalue%%%
呼び出しを使用して、名前が他の変数に依存する変数を設定します。変数の命名規則を使用すると、慎重な命名規則を使用して、配列や辞書などのデータ コレクションをエミュレートできます。somevalue を囲む 3 つの % は、呼び出し後、set が呼び出される前に、1 つの % で囲まれた 1 つの変数名として評価されるようにします。これは、行内の 2 つの % が 1 つの % 文字にエスケープされ、再度展開されることを意味するため、 somevalue は実質的に名前ポインターです。
call set TempVar=%%SomeEnvVariable_%extension%%%
これを一時変数と一緒に使用して値を取得し、それをロジックで使用できます。これは、遅延変数展開と組み合わせて使用する場合に最も役立ちます。
この方法を適切に使用するには、遅延変数展開を有効にする必要があります。デフォルトではオフになっているため、最初の指示の 1 つとしてこれを記述して、スクリプト内で有効にすることをお勧めします。
setlocal EnableDelayedExpansion
パス(または必要に応じて他のパスのような文字列)で実行可能ファイルを検索する:
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:\>
::
コメントの代わりに使用するREM
場合: 注意してください! ::
コメントのように機能する CALL ラベルの特殊なケースです。FOR ループや IF ループなど、括弧内で使用すると、関数は途中で終了します。デバッグするのは非常にイライラします!
完全な説明については、 http://www.ss64.com/nt/rem.htmlを参照してください。
(私はまだコメントする価値がないので、上記の最初の言及にコメントの代わりに新しい回答として追加します:0)
最近では多くの人が GOTO :EOF を使用してバッチ ファイルを終了しますが、この目的で EXIT /B を使用することもできます。
EXIT /B を使用する利点は、EXIT /B の後にエラー レベルを追加できることです。そのエラー レベルで終了します。
ENDLOCAL が使用する行のローカル変数は引き続き解析されます。これにより、次のようなトリックが可能になります。
ENDLOCAL & SET MYGLOBAL=%SOMELOCAL% & SET MYOTHERGLOBAL=%SOMEOTHERLOCAL%
これは、呼び出し元のコンテキストに結果を送信する便利な方法です。具体的には、%SOMELOCAL% は ENDLOCAL が完了するとすぐに範囲外になりますが、それまでに %SOMELOCAL% は既に展開されているため、ローカル変数を使用して呼び出しコンテキストで MYGLOBAL が割り当てられます。
同じ理由で、次のことを行う場合:
ENDLOCAL & SET MYLOCAL=%MYLOCAL%
新しい MYLOCAL 変数が、意図したローカライズされた変数ではなく、実際には通常の環境変数として使用されていることがわかります。
cmd.exe のクイック編集モードが私のお気に入りです。これは少し話題から外れますが、コマンド シェルと対話するときは命の恩人になる可能性があります。いいえ、私は誇張しているわけではありません.caret-capitol-vは、死ぬまでに特定の回数しか表示されません。見れば見るほど死ぬのが早い。
(これは UI からも設定できますが、これはおそらくより良い方法です。説明についてはコメントを参照してください。また、これを行うための優れた 1 行のスクリプトもあります。)
コピーするには、左クリックしてドラッグして選択し、右クリックしてコピーします。貼り付けるには、右クリックします。
もう^V^V^V^V^V^V^V^V^V^V^V^V^V^V!!!
くそ、私はちょうど誰かを殺したようだ。ごめん!
コール セット - 環境変数を数レベル深く展開します。
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
サブルーチン (出力 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
errorlevel を使用して、バッチファイルが実行されるシステム (現在のディレクトリまたはパス) で特定のプログラムが利用可能かどうかを確認できます。これが機能するには、テストしているプログラムを実行し、終了し、終了コードを設定する必要があります。私が使用する例では -? myExe への引数として、ほとんどの CLI プログラムには -h、--help、-v などの同様の引数があります。
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)
)
はい、errorlevel を errCode に割り当てるのではなく直接テストできますが、この方法では、テストと条件の間にコマンドを配置して、必要に応じて繰り返し条件をテストできます。
> con
バッチの出力が既に構文を介してファイルにリダイレクトされている場合でも、出力をコンソールにリダイレクトします。
例: foo.cmd:
echo a
echo b > con
呼び出し:
foo.cmd > output.txt
これにより、まだコンソールに移動することになります"a"
。output.txt
"b"
SHIFT
これは、コマンド ラインでスクリプト (またはサブルーチン) に渡される可変数の引数を反復処理する方法です。最も単純な使用法では、%2 を %1 に、%3 を %2 に、というようにシフトします。(パラメータを SHIFT に渡して複数の引数をスキップすることもできます。) これにより、コマンドは「破壊的」になります (つまり、%1 は永久に消えます) が、サポートされる引数の最大数をハードコーディングすることを避けることができます。
コマンドライン引数を 1 つずつ処理する短い例を次に示します。
:ParseArgs
if "%1"=="" (
goto :DoneParsingArgs
)
rem ... do something with %1 ...
shift
goto :ParseArgs
:DoneParsingArgs
rem ...
「ディレクトリの削除」のサブディレクトリ オプション:
rd /s /q junk
スクリプト内からstdinを解析するには、FORコマンドとFINDコマンドを使用したそのトリックが必要です。
for /f "tokens=*" %%g in ('find /V ""') do (
:: do what you want with %%g
echo %%g
)
ブランチ間でファイルをコピーする場合の便利なトリック:
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%環境変数と環境変数置換の両方を使用します。
現在の日、月、年を取得します(ロケールに依存しません)。
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%
CHOICEコマンドは、ユーザーに複数のオプションの 1 つを求めるプロンプトを (1 回のキー押下で) 表示します。
@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
)。
数値変数を含むループの正しい形式は次のとおりです。
for /l %%i in (startNumber, counter, endNumber) do echo %%i
cmd.exe自体の/ cparamは、実行してからこれらのコマンドを実行するように指示します。
私は自分が頻繁にやっていることに気づきました:
win + r、cmd RETURN、ping google.com RETURN
しかし今私はただします:
win + r、cmd / c ping google.com RETURN
はるかに高速。また、pstoolsを使用していて、psexecを使用してリモートマシンでコマンドライン機能を実行する場合にも役立ちます。
編集: / k同じように機能しますが、プロンプトは開いたままになります。これはもっと頻繁に役立つかもしれません。
パイプ'|'を使用して、フォルダ内のファイル内の文字列を検索します 指図:
dir /b *.* | findstr /f:/ "thepattern"
価値のあることとして、これは Windows CMD またはバッチ ファイルの非常に優れたオンライン リファレンスです。そこから、私が知らなかったいくつかのことを学びました。
バッチ ファイル内の配列。
値を設定します。
set count=1
set var%count%=42
コマンドラインで値を抽出します。
call echo %var%count%%
バッチ ファイルで値を抽出します。
call echo %%var%count%%%
余分な機銃掃射 % 記号に注意してください。
このテクニックは少し難解に見えるかもしれませんが、非常に便利です。上記は、説明したようにvar1 (つまり 42) の内容を出力します。他の変数をvar1の値に設定したい場合は、 echoコマンドをsetに置き換えることもできます。以下は、コマンドラインでの有効な割り当てです。
call set x=%var%count%%
次に、va1の値を確認します。
echo %x%
正規表現をサポートする Findstr:
findstr "^[0-9].*" c:\windows\system32\drivers\etc\hosts
forfilesは、たとえば、2 日以上経過したすべてのファイルを再帰的に削除するのに非常に便利です。
forfiles /D -2 /P "C:\Temp" /S /C "cmd /c del @path"
Doskey マクロ。
私はこれについての参照を長い間失っていましたが、それでも良いアイデアであり、共有する価値があると思います.
バッチ ファイルと doskey スクリプトを 1 つのファイルにマージできます。これは少し巧妙すぎるように思えるかもしれませんが、うまくいきます。
;= @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 マクロ ';' を定義することで機能します。これは、バッチ ファイルとして解釈されると、適切に (または黙って) 無視されます。
ここにリストされているバージョンを短縮しました。さらに必要な場合は、ここに移動してください。
を使用したインライン コメント&::
。
:: 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
最終的な結果は、コマンドを実行してから何もしないコマンドを実行することで、コメントに近づきます。
これはすべての状況で機能するわけではありませんが、便利なハックになるには十分な頻度で機能します。
コマンドの出力をファイルに簡単にリダイレクトできることは非常に便利です。
DIR *.txt > tmp.txt
DIR *.exe >> tmp.txt
一重矢印はファイルを作成または上書きし、二重矢印はファイルに追加します。これで、テキスト エディターで tmp.txt を開いて、さまざまな操作を実行できるようになりました。
pushd を UNC パスに使用すると、一時的なドライブ マッピングが作成され (Z から始まり、次に利用可能な文字を見つけるために逆方向に作業します)、そのドライブとパスに移動します。コマンド プロンプトを popd または終了すると、一時的なマッピングはなくなります。
C:\>pushd \\yourmom\jukebox
Z:\>pushd \\yourmom\business
Y:\>
また、コマンド ライン環境のヒントほどのバッチ ヒントではありませんが、コマンド ラインで pushd と popd およびネットワーク共有を使用して作業している場合は、プロンプトを $+ (show pushd stack depth) および$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>
上記と同様に、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が一度に1行を解決する方法により、親スコープのx変数に値を抽出できます。
ここでは、特定のディレクトリをスキャンして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で直接指定できるため(例:-cp"。\lib *")、1.6では必要ありません。
エラーで保釈します。
IF "%errorlevel%" NEQ "0" (
echo "ERROR: Something broke. Bailing out."
exit /B 1
)
対話型バッチ スクリプトの入力を非表示にします。
@echo off
echo hP1X500P[PZBBBfh#b##fXf-V@`$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 行の複数のコマンド:
& 2 つのコマンドを結合するために使用され、command1 を実行してから command2 を実行します
&& 条件付きの組み合わせで、command1 が正常に完了した場合に command2 を実行します
¦¦ Command2 は、command1 が正常に完了しなかった場合にのみ実行されます。
例:
:: ** 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
「%」ディレクティブを指定しなくても、環境変数に基づいてディレクトリを変更できます。指定された変数が存在しない場合は、ディレクトリ名を試してください。
@if defined %1 (call cd "%%%1%%") else (call cd %1)
エラーレベルを任意の数値に設定する方法:
CMD /C 出口番号
を使用してファイルから環境変数を設定するSET /P
SET /P SVNVERSION=<ver.tmp
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
周囲の引用を削除します。
for /f "useback tokens=*" %%a in ('%str%') do set str=%%~a
最近、VS prebuild イベントによって呼び出されるバッチ ファイルを作成する必要があり、プロジェクト ディレクトリをパラメーターとして渡したいと考えています。バッチ ファイルでは、パスをネストされたサブフォルダー名と連結する必要がありますが、最初に周囲の引用符を削除する必要があります。
新しいファイルを作成して編集を開始する
copy con new.txt
This is the contents of my file
^Z
Ctrl+Z は ASCII EOF 文字を送信します。これは、bash のヒアドキュメントのようなものです。
cat <<EOF > new.txt
This is the contents of my file
EOF
コピーを使用してファイルを追加します。
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!
ディレクトリ ツリーで文字列を再帰的に検索します。
findstr /S /C:"string literal" *.*
正規表現も使用できます。
findstr /S /R "^ERROR" *.log
再帰的なファイル検索:
dir /S myfile.txt
すべてのドライブを一覧表示します。
fsutil fsinfo drives
シンボリック リンク:
mklink /d directorylink ..\realdirectory
mklink filelink realfile
このコマンドは、Windows Server 2008 以降 (Vista および Windows 7 を含む) でネイティブです (一部の Windows リソース キットにも含まれています)。
スクリプトでコマンド拡張シェルオプションを使用する場合は、スクリプトの最初に次のトリックを実行することを強くお勧めします。
--http: //www.ss64.com/nt/setlocal.htmlから貼り付けられた情報
引数を指定すると、SETLOCALはERRORLEVELを設定します。2つの有効な引数の1つが指定されている場合はゼロになり、そうでない場合は1つになります。
これをバッチファイルで使用して、次の手法を使用して、コマンド拡張機能が使用可能かどうかを判断できます。
VERIFY errors 2>nul
SETLOCAL ENABLEEXTENSIONS
IF ERRORLEVEL 1 echo Unable to enable extensions
これは、「VERIFYエラー」がERRORLEVELを1に設定し、拡張機能が使用できない場合(たとえば、スクリプトがcommand.comで実行されている場合)、SETLOCALがERRORLEVEL値のリセットに失敗するために機能します。
コマンド拡張機能が永続的に無効になっている場合、SETLOCALENABLEEXTENSIONSはそれらを復元しません。
このWindows XP Commandsリファレンスと、上部のSyntaxリンクがとても気に入っています。他の回答ですでに見つかったヒントやコツの多くをカバーしています。
ログファイルなどに使用する現在の日付/時刻を取得するには、バッチファイルでこれを使用します。
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
実行中にバッチ ファイルを変更できます。たとえばpause
、バッチ ファイルが終了する前に結果を確認したい場合は、実行中にファイルの末尾に忘れたファイルを追加できます。
実行中のバッチファイルの変更を参照してください
個人的には、これは機能というより落とし穴だと思っています。
不明な数のパラメーターをバッチ ファイルに渡す場合 (複数のファイルをバッチ ファイルにドラッグ アンド ドロップして起動する場合など)、各パラメーター変数を名前で参照できます。
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 はすべてのパラメータを 1 つ下に移動するため、%2 は %1 になり、%3 は %2 になります。
よく使用するディレクトリへのクイック ショートカットとして使用します。私のPATHのディレクトリにある「sandbox.bat」という名前のサンプルファイル
EXPLORER "C:\Documents and Settings\myusername\Desktop\sandbox"
スクリプトの呼び出しは WIN+R だけです --> サンドボックス
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
)
非常に高速で効果的です。
HELP
異なる OS バージョンで作業する場合、どのコマンドがネイティブで使用できるかを知ることが重要です。コマンド プロンプトで HELP と入力すると、使用可能なコマンドとその機能の簡単な説明が表示されます。
cmd.exe /?
これにより、コマンド プロンプトを起動するためのすべてのコマンド ライン パラメーターと、システム全体の動作を変更するレジストリ調整が一覧表示されます。
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 :)
EDLIN コマンドもあります。かつて行ベースのテキスト編集に使用されていた古いツールかもしれませんが、コマンド ラインから制御できるという事実は、バッチ スクリプト作成にかなり役立ちます。主に、EDLIN を使用する他の場合と同様に、利用できる唯一のツール。結局のところ、EDLIN は、よほど自虐的でない限り、通常はテキスト編集に使用したいツールではありません。ティム・パターソン (この記事を書いた人物) の言葉を引用すると、「IBM がそれを窓から放り出さずに使用していると聞いたとき、私は愕然としました。」
注: EDLIN は、編集するファイルに昔ながらの EOF (1A) マーカーを追加します。それらを削除する必要がある場合は、おそらく DEBUG を使用する必要があります。
環境変数の合計サイズを取得するための非常に古い (ca 1990) トリック:
set > test
dir test
del test
数値カウンター (出力 1 から 10) を持つループの場合:
for /l %i in (1,1,10) do echo %i
行ベースの実行
ほとんどの場合、明らかな利点ではありませんが、実行中に何かを更新しようとする場合に役立ちます。例えば:
UpdateSource.bat
copy UpdateSource.bat Current.bat
echo "Hi!"
Current.bat
copy UpdateSource.bat Current.bat
ここで、Current.bat を実行すると、この出力が生成されます。
HI!
ただし、バッチの実行は行番号で進行することに注意してください。このような更新では、重要な行の行番号がまったく同じでない場合、スキップしたり、行を戻したりする可能性があります。
これは、バッチ ファイルを何度もクリックせずに My Nant Build スクリプトを連続して実行するために使用する 1 つのトリックです。
:CODELINE
NANT.EXE -buildfile:alltargets.build -l:build.log build.product
@pause
GOTO :CODELINE
何が起こるかというと、ソリューションの構築が完了すると、一時停止されます。その後、何かキーを押すと、ビルド スクリプトが再実行されます。私が言わなければならない非常に便利。
このバッチ ファイルは、コマンド ライン パラメーターとして単純なファイルとディレクトリの両方で機能します (任意の順序で混在させることができます)。ループは、指定されたファイルに対してコマンド (この例では「echo」) を実行します。パラメーターがディレクトリの場合、その中の各ファイルに対してコマンドを再帰的に実行します。
@echo off
for /f "delims=" %%f in ('dir %* /a-d /b /s') do echo %%f
バッチ スクリプトの最も一般的な要件の1 つは、後で確認するために生成された出力をログに記録することです。はい、stdout と stderr をファイルにリダイレクトできますが、ログ ファイルを末尾にしない限り、何が起こっているのかを確認できません。
そのため、ロガーのような stdout/stderr ログ ユーティリティを使用してバッチ スクリプトを実行することを検討してください。ロガーは出力をタイムスタンプと共にログに記録し、スクリプトの進行状況を引き続き確認できます。
さらに別の stdout/stderr ロギング ユーティリティ
Yet another stdout/stderr logging utility [2010-08-05]
Copyright (C) 2010 LoRd_MuldeR <MuldeR2@GMX.de>
Released under the terms of the GNU General Public License (see License.txt)
Usage:
logger.exe [logger options] : program.exe [program arguments]
program.exe [program arguments] | logger.exe [logger options] : -
Options:
-log <file name> Name of the log file to create (default: "<program> <time>.log")
-append Append to the log file instead of replacing the existing file
-mode <mode> Write 'stdout' or 'stderr' or 'both' to log file (default: 'both')
-format <format> Format of log file, 'raw' or 'time' or 'full' (default: 'time')
-filter <filter> Don't write lines to log file that contain this string
-invert Invert filter, i.e. write only lines to log file that match filter
-ignorecase Apply filter in a case-insensitive way (default: case-sensitive)
-nojobctrl Don't add child process to job object (applies to Win2k and later)
-noescape Don't escape double quotes when forwarding command-line arguments
-silent Don't print additional information to the console
-priority <flag> Change process priority (idle/belownormal/normal/abovenormal/high)
-inputcp <cpid> Use the specified codepage for input processing (default: 'utf8')
-outputcp <cpid> Use the specified codepage for log file output (default: 'utf8')
ファイルの最初の行から環境変数を設定するには、これを使用します。
rem a.txt contains one line: abc123
set /p DATA=<a.txt
echo data: %DATA%
これは次のように出力されます: abc123
テキストのランダムな行を抽出する
@echo off
:: Get time (alas, it's only HH:MM xM
for /f %%a in ('time /t') do set zD1=%%a
:: Get last digit of MM
set zD2=%zD1:~4,1%
:: Seed the randomizer, if needed
if not defined zNUM1 set /a zNUM1=%zD2%
:: Get a kinda random number
set /a zNUM1=zNUM1 * 214013 + 2531011
set /a zNUM2=zNUM1 ^>^> 16 ^& 0x7fff
:: Pull off the first digit
:: (Last digit would be better, but it's late, and I'm tired)
set zIDX=%zNUM2:~0,1%
:: Map it down to 0-3
set /a zIDX=zIDX/3
:: Finally, we can set do some proper initialization
set /a zIIDX=0
set zLO=
set zLL=""
:: Step through each line in the file, looking for line zIDX
for /f "delims=@" %%a in (c:\lines.txt) do call :zoo %zIDX% %%a
:: If line zIDX wasn't found, we'll settle for zee LastLine
if "%zLO%"=="" set zLO=%zLL%
goto awdun
:: See if the current line is line zIDX
:zoo
:: Save string of all parms
set zALL=%*
:: Strip off the first parm (sure hope lines aren't longer than 254 chars)
set zWORDS=%zALL:~2,255%
:: Make this line zee LastLine
set zLL=%zWORDS%
:: If this is the line we're looking for, make it zee LineOut
if {%1}=={%zIIDX%} set zLO=%zWORDS%
:: Keep track of line numbers
set /a zIIDX=%zIIDX% + 1
goto :eof
:awdun
echo ==%zLO%==
:: Be socially responsible
set zALL=
set zD1=
set zD2=
set zIDX=
set zIIDX=
set zLL=
set zLO=
:: But don't mess with seed
::set zNUM1=
set zNUM2=
set zWORDS=