kool tools & tips INDEXへ
kool tips
長いファイルパスをDOS窓で打つのが面倒な時 ▲TOP
エクスプローラ上でファイルやディレクトリを選択し、そのままDOS窓にドラッグ&ドロップすると、
プロンプトにフルパスが表示されます。
パスにスペースが含まれる場合も、自動的にダブルクォートで括ってくれます。
con! 作れないファイル達 ▲TOP
con, prn, nul, aux, LPT~9 COM1~9 CLOCK$, CONFIG$ etc.
上記のデバイス名と同名の名前を持つファイル、ディレクトリは作れません。
DOS の時代から現在も連綿と引き継がれる遺物って奴ですね。
ダイアログのテキストをコピーする ▲TOP
メッセージのダイアログが表示された時、その場で Ctrl+C でコピーすると、
ダイアログに表示されているテキスト情報をクリップボードにコピーできます。
net send コマンドで改行する ▲TOP
net send コマンドは相手に IP Messenger などがインストールされていなくても、
メッセージを送れるので便利ですが、改行ができないのが難点。
と、思っていたら改行できるんですね。
net send [送り先] メッセージCtrl+Tメッセージ
で、改行できます。
では、バッチファイルで実行したい場合はどうでしょう。
実行してみればわかりますが、これは単なる「^(キャレット)」+「T」と
してしか認識されません。つまり改行されないんです。
プロンプトからコピって、バッチファイルにペーストしても同じ事です。
では、どうするか。
私は、
echo Ctrl+T
をプロンプトに表示し、それ(網掛けの豆腐になっている)をバッチ
ファイルにコピペして使用しています。(^_^;
因みに、この豆腐、debugコマンドで見ると、asciiの0x14になっていました。
set netsendcr=■ ←(これは単なる四角です。HTMLに入れるのはちょっとハバカラれるので)
みたいに変数に入れておけば、
net send [送り先] メッセージ%netsendcr%メッセージ
風に使えるでしょう。
と言うか、私は実際そのようにして使っています。これでバッチからでも net send で改行が可能になります。
echoコマンドで改行する ▲TOP
echo;
以下はダメです。
echo ;
コマンドの途中で改行する ▲TOP
コマンドを打っている途中で改行したい時は「^(キャレット)」を打てばそこで改行されます。
echo コマンドの途中^
で改行するとプロンプトに「More?」と表示されるので、続けて打っていく事ができます。
終わりたい時は、空改行すればOK。
1行に複数のコマンドを連結 ▲TOP
& を使って複数のコマンドを1行に書く事ができます。
echo aaaa & echo bbbb
pushdコマンドでネットワークドライブの割り当て ▲TOP
cdコマンドを UNCパス(\\パス)に対して使う事はできませんが、
実は、pushd は使う事ができます。
何と、割り当て未済のドライブを勝手に割り当ててくれるのです。
(未検証ですが、多分2000とXP以降のみでしょう)
popdするか、プロンプトを閉じると割り当ては勝手に解除されます。
(バッチ中断やエラー時は解除されないので注意)
こんな感じです。Try it !
C:\>pushd \\10.xxx.xxx.xxx\work\mydocs
Z:\mydocs>
Z:\mydocs>popd
C:\>
デスクトップの表示 ▲TOP
「デスクトップの表示.scf」だとウィンドウが全て隠れてしまうのがイマイチ。
さりとてウィンドウ裏のアイコンを触るフリーウェアとかを入れるのもなぁ。
と思って考えたのがコレです。ツールバーのクイック起動に入れて使っています。
%windir%\explorer.exe "%USERPROFILE%\デスクトップ"
送るに送る ▲TOP
SendToフォルダにSendToのショートカットを作り、
「送るに送る」と言う名前にしておく。
後は、ショートカットを作った時に、この「送るに送る」で
送れば、SendToフォルダを開く必要なし。
もしかして、何かもっとクールな方法でやっているのか?皆さんは!
FOR文使用時の留意点 ▲TOP
FOR文で、LOOPを制御する %変数 を使う場合、
バッチファイルでは %%変数
プロンプトで直接入力の時は %変数
と表記する必要があります。
原則的にバッチで使用する事を前提としているため、FOR文の中で使用している変数について、
ここでは、%%i のように表記しています。
つまり、例文を、そのままプロンプトにコピペするとエラーになりますので注意してください。
キー入力の値を変数に格納 ▲TOP
echo 入力してください(入力後、改行し、終端文字CTRL+Zを入力)
set cmd=
for /f %%a in ('type con') do set cmd=%%a
echo %cmd%
※W2K,XP以降であれば、後述の「キー入力の値を変数に格納-2」をご覧ください
日付や時間をファイル名に ▲TOP
%date% や %time% の書式は、環境によって異なると思われるので注意。
set mydate=%date%
set mytime=%time%
echo %mydate% %mytime%
REM YYYYMMDD.txt 作成
type nul>%mydate:~2,4%%mydate:~7,2%%mydate:~10,2%.txt
REM YYYYMMDDHHMISS.txt 作成
type nul>%mydate:~2,4%%mydate:~7,2%%mydate:~10,2%%mytime:~0,2%%mytime:~3,2%%mytime:~6,2%.txt
ループ処理(複数ファイルを選択してドラッグ&ドロップ) ▲TOP
以下のバッチファイルを作っておき、エクスプローラで選択してショートカットにドラッグ&ドロップするか、
右クリック-送る で選択したファイルに対してLOOP処理を行います。
:start
if "%1"=="" goto end
rem ここで何かの処理(選択したファイルに対して処理を行う)
echo %1
shift
goto start
:end
ループ処理(テキストを1行ずつ読んで、その内容について処理を行う) ▲TOP
以下の csplit.bat の例では、CSVファイルを読んで、任意の列を表示します。
REM Usage: csplit {列番号} {対象ファイルパス}
for /F "eol=; tokens=%1 delims=," %%i in (%2) do @echo %%i
eval(変数の内容を実行) ▲TOP
以下の eval.bat の例では、標準入力の内容を実行します。
for /L %%f in (1,1,1) do %1 %2 %3 %4 %5 %6 %7 %8 %9
※これって、cmd /c 文字列 で、いんでないかい?(気づけよ(^^;)
キー入力の値を変数に格納-2 ▲TOP
echo 入力してください(入力後、改行)
set /p cmd=
四則演算結果や16進→10進変換の結果を変数に格納 ▲TOP
四則演算結果や16進→10進変換の結果を格納する事も可能です。
REM 四則演算
set /a 1+(34*2)
REM 16進→10進変換
set /a 0xff
REM 四則演算結果を格納
set /a result=1+(34*2)
REM 16進→10進変換結果を格納
set /a result=0xff
標準出力されたコマンドの結果を変数に格納 ▲TOP
UNIX系OSのシェルスクリプトではお馴染みですが、Windowsのバッチではちょっと泥臭い事をする必要があります。
しかも制限があります。
実行してみるとわかるとおり、日本語の場合の振る舞いがイマイチなのです。
半角英数字であれば、まず問題ないと思われます。
一応、解決方法(?)も考えてみたのですが、
要はどう言う事かと言うと、どうも「最後に登場した2バイト文字の後ろに、
2バイト文字の出現回数と同数の半角文字を付加」すれば何故かOK(笑)、
って事みたいなんですねえ。全角半角をテンコシャンコに混在させても同じでした。
とは言え、これじゃなあ。。。
乞う!ナイス・ソリューション。
REM これだとイマイチ
for /f "usebackq tokens=*" %%i IN (`echo あああ`) DO @set myvar=%%i
REM これだと一応OK
for /f "usebackq tokens=*" %i IN (`echo あああ123`) DO @set myvar=%i
変数の文字列を置換 ▲TOP
REM %DATE%変数の表示書式を変えてみる
echo %DATE:/=-%
エラーレベルのクリア ▲TOP
「set ERRORLEVEL=0 じゃダメなのか?」
ダメです。これをやってもエラーにはなりませんが、
そのセッション上で、どんな間違ったコマンドを発行しても、
ERRORLEVEL=0 のままになってしまいます。
これは単なるコンスタント値のバッチ環境変数"ERRORLEVEL"でしかなく、
しかも、ここでセットした値の方が優先されてしまうからです。
要は、「とにかく ERRORLEVEL=0 になるようなコマンド」
を発行して、nulデバイスに放り込んでやればいいわけですから、
私が使っているのはこれ。
REM エラーレベルのクリア
date /t>nul
エラーメッセージを標準出力に表示させない ▲TOP
標準出力のリダイレクト先を変えてあげればよいわけです。
例えば、以下のコマンドを実行すると
mkdir con
⇒通常はエラーメッセージが stderr に表示されます。
これを以下のようにすれば、
mkdir con >C:\temp.txt 2>&1
⇒エラーメッセージも stdout に出力(=2 のストリームも 1 に出力)されます。
さらに「どこにも出したくない」のであれば
mkdir con >nul 2>&1
こんな感じで。
応用(ファイル/ディレクトリ情報を取得) ▲TOP
endofthis後の変数削除はご随意に。(取得した情報をバッチの中で使うかどうかで分かれます)
@echo off
REM ####################################################################
REM ## fileinfo.bat
REM ## ファイル情報取得
REM ####################################################################
if "%~1" == "" (
echo fileinfo ファイル情報取得
echo Usage: fileinfo [ファイル名 ^| ディレクトリ ^| フルパス]
goto endofthis
)
set fileinfo_noQuote=%~1
set fileinfo_fullPath=%~f1
set fileinfo_path=%~p1
set fileinfo_drive=%~d1
set fileinfo_file=%~n1
set fileinfo_ex=%~x1
set fileinfo_short=%~s1
set fileinfo_at=%~a1
set fileinfo_time=%~t1
set fileinfo_size=%~z1
echo 引用符削除:%fileinfo_noQuote%
echo 完全修飾パス名:%fileinfo_fullPath%
echo パス名:%fileinfo_Path%
echo ドライブ文字:%fileinfo_drive%
echo ファイル名:%fileinfo_file%
echo ファイル拡張子:%fileinfo_ex%
echo ショートネーム:%fileinfo_short%
echo 属性:%fileinfo_at%
echo 日付/時刻:%fileinfo_time%
echo ファイルサイズ:%fileinfo_size%
echo;
if "%fileinfo_at%" == "" (
echo このファイル/ディレクトリ %1 は存在しません
goto endofthis
)
if "%fileinfo_at:~0,1%" == "d" (
echo ディレクトリ %1 が存在します
) else (
echo ファイル %1 が存在します
)
echo;
:endofthis
rem set fileinfo_noQuote=
rem set fileinfo_fullPath=
rem set fileinfo_path=
rem set fileinfo_drive=
rem set fileinfo_file=
rem set fileinfo_ex=
rem set fileinfo_short=
rem set fileinfo_at=
rem set fileinfo_time=
rem set fileinfo_size=
応用(サブディレクトリも含めて更新日順にファイル一覧を表示する) ▲TOP
パスが浅いと大量のサブディレクトリ検索を行うのでとんでもない事になります。
@echo off
REM ####################################################################
REM ## newlist.bat
REM ## サブディレクトリも含めて更新日順にファイル一覧を表示する
REM ####################################################################
set targetDir=%~1
if "%targetDir%" == "" (
echo newlist サブディレクトリも含めて更新日順にファイル一覧を表示する
echo Usage: newlist ディレクトリ(最後に \ を付けない)
echo;
echo; ex. ^>newlist c:\texts
echo;
echo ※パスが浅いと大量のサブディレクトリ検索を行うので、
echo とんでもない事になる!
goto endofthis
)
type nul> %tmp%\newlist.txt
REM 言うまでもないが、ここでパイプしてソートしてリダイレクトしても無駄
FOR /F "usebackq delims==" %%i IN (`dir /s /b %targetDir%\*.*`) DO @echo %%~ti %%i >> %tmp%\newlist.txt
REM GNU系のsortに入らないようにフルパスで書く
C:\WINNT\system32\sort.exe %tmp%\newlist.txt
:endofthis
set targetDir=
if exist %tmp%\newlist.txt del %tmp%\newlist.txt
応用(上記とは違うアプローチによるファイルリスト作成) ▲TOP
ファイルを選択して「送る」と一覧をテキストに表示。
rem @echo off
REM ####################################################################
REM ## filelist.bat
REM ## ファイルリスト作成
REM ##
REM ## ※SendToフォルダに "選択範囲のファイル名を返す" の名前で
REM ## ショートカットを作っておくとよい
REM ##
REM ####################################################################
type nul> %temp%\flist.txt
:START
IF "%~1"=="" GOTO END
dir "%~1" /B>> %temp%\flist.txt
SHIFT
GOTO START
:END
start %temp%\flist.txt
応用(上記ファイルリスト作成の再帰版) ▲TOP
ファイルを選択して「送る」と一覧をテキストに表示(階層下まで再帰検索)。
rem @echo off
REM ####################################################################
REM ## filelistall.bat
REM ## ファイルリスト作成(フルパス再帰版)
REM ##
REM ## ※SendToフォルダに "選択範囲のフルパスを返す(再帰)" の名前で
REM ## ショートカットを作っておくとよい
REM ##
REM ####################################################################
type nul> %temp%\flistall.txt
:START
IF "%~1"=="" GOTO END
dir "%~1" /S /B>> %temp%\flistall.txt
SHIFT
GOTO START
:END
start %temp%\flistall.txt
応用(「どこでも窓」=どこからでもDOS窓を開く) ▲TOP
ディレクトリまたは、ファイルを選択して、送ると、その場でDOS窓を開ける。
どこにいても cl , どこにいても bcc32 , どこにいても javac ,
そんなスクラッチャーな人に。
pushd を使っているので、UNCパス(\\パス)上のディレクトリでもOK。
cmd.exe が2つ上がってしまうのが難点。
@echo off
REM ####################################################################
REM ## newcmd.bat
REM ## 任意の場所でコマンドプロンプトを開く
REM ## Microsoft の PowerToys "Open Command Window Here" や
REM ## "Command Prompt Here" の機能を代替するもの
REM ##
REM ## ※SendToフォルダに "New Prompt Here" とか "どこでも窓" などの
REM ## 名前でショートカットを作っておくとよい
REM ##
REM ## Usage :newcmd [パス]
REM ##
REM ####################################################################
REM ファイル名を除いたパスをセット
set newdir=%~dp1
REM ファイルかディレクトリか(属性の1桁目が"d"ならディレクトリ)
set ford=%~a1
set ford=%ford:~0,1%
REM ディレクトリであればフルパスセット
IF "%ford%" == "d" set newdir=%~1
REM cmdを開いて、引数のパスに pushd する
cmd /K "pushd %newdir%"
:endofthis
set newdir=
set ford=
応用(日付書式の取得) ▲TOP
@echo off
REM ####################################################################
REM ## getDateFmt.bat
REM ## 日付書式の取得(レジストリの日付書式使用)
REM ####################################################################
REM WSHでレジストリ検索でもよいが、ちょっとバッチオンリーに拘ってみたり
regedit /e/a %tmp%\expreg.txt "HKEY_CURRENT_USER\Control Panel\International"
REM 日付書式取得
for /f "usebackq tokens=*" %%i IN (`findstr sShortDate %tmp%\expreg.txt`) DO @set dateFmt=%%i
set dateFmt=%dateFmt:"=%
set dateFmt=%dateFmt:~11,24%
REM 日付デリミタ取得
for /f "usebackq tokens=*" %%i IN (`findstr sDate %tmp%\expreg.txt`) DO @set dateFmtDelim=%%i
set dateFmtDelim=%dateFmtDelim:~9,1%
:endofthis
IF exist "%tmp%\expreg.txt" del "%tmp%\expreg.txt"
応用(経過時間を表示) ▲TOP
上記の getDateFmt.bat が同じディレクトリに必要です。
@echo off
REM ####################################################################
REM ## elaps.bat
REM ## 経過時間を表示
REM ## (日またぎも一応OK)
REM ####################################################################
set elaps_se=%~1
IF "%elaps_se%" == "" set elaps_se=999
REM 引数チェック
echo %elaps_se% | findstr [EeSs]>nul
IF not %ERRORLEVEL% == 0 (
echo elaps 経過時間を表示
echo Usage: elaps [S ^| E]
echo;
echo;ex.
echo;
echo; elaps S …開始
echo; elaps E …終了
echo;
goto endofthis
)
IF "%elaps_se%" == "s" set elaps_se=S
IF "%elaps_se%" == "e" set elaps_se=E
REM 日付書式取得済みならスキップ
IF NOT "%dateFmt%" == "" goto skip0
REM 日付書式取得
call %~p0getDateFmt
REM 日付書式取得できなかったら終了
IF "%dateFmt%" == "" goto endofthis
:skip0
IF "%elaps_se%" == "E" goto skip1
REM 初期化
set elps_start_datediffsec=
set elps_end_datediffsec=
set elps_endsec=
set elps_end_dd=
set elps_end_hh=
set elps_end_mi=
set elps_end_mm=
set elps_end_ss=
set elps_end_yy=
set elps_secdiff=
set elps_startsec=
set elps_start_dd=
set elps_start_hh=
set elps_start_mi=
set elps_start_mm=
set elps_start_ss=
set elps_start_yy=
REM 開始日時(datepart)取得
call %~p0getdatepart
set elps_start_yy=%dpart_yy%
set elps_start_mm=%dpart_mm%
set elps_start_dd=%dpart_dd%
set elps_start_hh=%dpart_hh%
set elps_start_mi=%dpart_mi%
set elps_start_ss=%dpart_ss%
goto endofthis
:skip1
REM 現在日時取得
call %~p0getdatepart
set elps_end_yy=%dpart_yy%
set elps_end_mm=%dpart_mm%
set elps_end_dd=%dpart_dd%
set elps_end_hh=%dpart_hh%
set elps_end_mi=%dpart_mi%
set elps_end_ss=%dpart_ss%
REM datepart取得できなかったら終了
IF "%elps_end_yy%" == "" goto endofthis
REM 日をまたいでいた時の対処
IF %elps_start_hh%%elps_start_mi%%elps_start_ss% GTR %elps_end_hh%%elps_end_mi%%elps_end_ss% (
set /a elps_start_datediffsec=1*24*60*60
set /a elps_end_datediffsec=2*24*60*60
) else (
set /a elps_start_datediffsec=1*24*60*60
set /a elps_end_datediffsec=1*24*60*60
)
REM set /a 08 と set /a 09 がエラーになるので逃げ
REM (理由は set /? で御確認の程を)
IF "%elps_start_hh:~0,1%" == "0" set elps_start_hh=%elps_start_hh:~1,1%
IF "%elps_start_mi:~0,1%" == "0" set elps_start_mi=%elps_start_mi:~1,1%
IF "%elps_start_ss:~0,1%" == "0" set elps_start_ss=%elps_start_ss:~1,1%
IF "%elps_end_hh:~0,1%" == "0" set elps_end_hh=%elps_end_hh:~1,1%
IF "%elps_end_mi:~0,1%" == "0" set elps_end_mi=%elps_end_mi:~1,1%
IF "%elps_end_ss:~0,1%" == "0" set elps_end_ss=%elps_end_ss:~1,1%
set /a elps_startsec=%elps_start_datediffsec%+%elps_start_hh%*60*60+%elps_start_mi%*60+%elps_start_ss%
set /a elps_endsec=%elps_end_datediffsec%+%elps_end_hh%*60*60+%elps_end_mi%*60+%elps_end_ss%
set /a elps_secdiff=%elps_endsec%-%elps_startsec%
rem echo %elps_start_hh%%elps_start_mi%%elps_start_ss%
rem echo %elps_end_hh%%elps_end_mi%%elps_end_ss%
echo 経過秒:%elps_secdiff%
:endofthis
応用(バッチ・ユーティリティ・パッケージ) ▲TOP
■概要
DOSコマンドのみで様々な処理を行なうためのバッチファイル集です。
まあ大方はお遊びです。(なにげに仕事でも使っていますが)
・環境変数まとめて破棄(initvar)
・日付関連ユーティリティ (utldt)
・配列関連ユーティリティ (utlary)
・文字列関連ユーティリティ (utlstr)
それぞれのユーティリティ間での依存関係は(今は)ありません。
配列関連のみ使用、日付関連のみ使用、と云った使い方が可能です。
■動作環境
Windows2000 および WindowsXP
■使い方
インストール後、/? 付きで実行してください。ヘルプを表示します。
または、各ユーティリティのディレクトリにある <ユーティリティ名>.txt
を参照してください。
各ディレクトリ内の test.txt はテスト時のプルーフです。
(実際には、ここに書かれている以外にもテストしていますが)
このファイルを見れば、具体的にどのような構文で書けばよいかが、わかると思います。
ex)
C:\>utldt /?
[関数一覧]
・環境変数まとめて破棄(initvar)
・日付関連ユーティリティ (utldt)
getDateFmt.bat(日付フォーマットの取得)
getDatePart.bat(日付の各値(年、月、日)を取得)
getDate.bat(現在日付の各値(年、月、日)を取得)
isBis.bat(閏年チェック)
isDate.bat(暦日チェック&月末日取得)
getRestDays.bat(入力日付から月末までの日数を取得)
dateAdd.bat(入力日付に日数を加えた日付を取得)
dateDiff.bat(日付間の日数を取得)
・配列関連ユーティリティ (utlary)
init.bat(配列を初期化)
setValue.bat(配列に値をセット)
getValue.bat(配列の値を取得)
find.bat(配列を検索して、該当するインデックスを取得)
・文字列関連ユーティリティ (utlstr)
wc.bat(文字列の文字数を取得する)
substring.bat(文字列の任意の開始位置から桁数分の文字列を取得する)
■インストール
ダウンロード⇒batutl.lzh
上記をダウンロード後、解凍したファイルの内、
initvar.bat
utlary.bat
utldt.bat
utlstr.bat
をパスが通るような場所に置いてください。
C:\binにパスが通っているとしたら、このようなディレクトリ構成にしてください。
C:\bin
│ initvar.bat
│ utlary.bat
│ utldt.bat
│ utlstr.bat
│
├─initvar
│ clear.bat
│ initvar.txt
│
├─utlary
│ find.bat
│ getValue.bat
│ init.bat
│ setValue.bat
│ test.txt
│ utlary.txt
│
├─utldt
│ dateAdd.bat
│ dateDiff.bat
│ getDate.bat
│ getDateFmt.bat
│ getDatePart.bat
│ getRestDays.bat
│ isBis.bat
│ isDate.bat
│ test.txt
│ utldt.txt
│
└─utlstr
substring.bat
test.txt
utlstr.txt
wc.bat
■その他
当然の如く、無償で無保証です。Your Own Risk でお願いします。
奇特にも仕事に流用しようなどと思われた場合は、エラー処理を十分に
厚くしてください。
大変遅い上にCPU食います。(特に再帰呼び出しを使用しているもの)
例えば、utldt の dateadd や datediff などで「数年またぎ」などと言う
事はしない方が身のためですw
テストして発見できた既知の問題で未解決部分が多々あります。
特に、引数のチェックは甘いです。
また、引数に制御文字列を片っ端から入れる、
などと言うテストはしていませんし、
リダイレクションやその他の記号を入れるようなテストも十分にはしていません。
くどいようですが、奇特にも仕事に流用しようなどと思われた場合は、
エラー処理を十分に厚くしてください。
このページの先頭へ
kool tools & tips INDEXへ