D&Dされたファイルパスを受け取る - バッチファイル
バッチファイルのアイコンに他のファイルをD&Dして処理を行いたい場合、ファイルパスの受け取り方。
基本
- 基本は「%1」で取得できる(複数ある場合は「%2」「%3」…)
- パス名に空白やカンマが含まれている場合、自動的に「“ “」でくくられる
- 「%~1」とすると、「” “」を除去できる
echo %1 rem C:\aaa\bbb.txt を与えた場合 => C:\aaa\bbb.txt rem C:\aaa\b b b.txt を与えた場合 => "C:\aaa\b b b.txt" echo %~1 rem C:\aaa\b b b.txt を与えた場合 => C:\aaa\b b b.txt
パスの一部だけ取得
ファイル名だけ、親ディレクトリだけ、拡張子だけ、など一部分を取り出したい場合、引数と、FORループ内定義変数に限り、特殊な表記が使える。
バッチファイルでファイルパスからファイル名や拡張子を自由に取り出す方法 - みちしるべ
- たとえば元のファイル名の末尾に「_bak」と付け加えたい場合は「拡張子を除いたパス+“_bak”+拡張子」
- 元の「” “」は外れているので、結果を更に何かの引数に使いたい場合は、改めてくくる必要がある
rem C:\aaa\b b b.txt を与えた場合 echo "%~dpn1_bak%~x1" rem => "C:\aaa\b b b_bak.txt" rem 一般の変数には使えない set FP = "C:\aaa\ccc.txt" echo %~nFP% rem => %~nFP% (ccc.txtとはならない)
ループ
D&Dされた複数ファイルに同じ処理をしたい場合、FORループにする。「%*」で引数全てを示す。
for %%i in (%*) do ( echo %%i )
ループの注意点
ただし、ファイルパスが、空白を含まず「)」半角閉じ括弧を含む場合、エラーになる。さすがバッチ!そんな単純なことでエラーになるなんてそこにシビれないし憧れない
バッチのForループで括弧を含む引数を使いたい。 - マイクロソフト コミュニティ
原因は、内部的には「%*」がこう展開されてしまうため。「aaa(bbb」までが括弧だと解釈され、残りが構文的におかしいのでエラーになる。
rem > test.bat aaa(bbb).txt ccc(ddd).txt と引数を与えて実行 for %%i in (aaa(bbb).txt ccc(ddd).txt) do ( echo %%i )
遅延評価を使うと、回避できる。
setlocal enabledelayedexpansion set x=%* for %%i in (!x!) do ( echo %%i )
使用例
D&Dされたファイルを個別に7-Zipで.7z圧縮
- each7z.bat
@echo off rem 「元の(ファイル名|フォルダ名).7z」で個別圧縮 setlocal enabledelayedexpansion set x=%* for %%i in (!x!) do ( "7z.exeまでのパス" a -t7z %%~ni.7z %%i )
少し気にかけなければならないのが作業フォルダ。上のバッチでは圧縮ファイルは、作業フォルダの中に作成される。
バッチファイルが C:\aaa\each7z.bat
にあり、そこに C:\bbb\raw.txt
をD&Dすると、作業フォルダは自動的に C:\bbb
(D&D元のフォルダ)となる。
つまり、raw.txt
と同じ場所に raw.7z
が作成される。これが自然だろう。
一方、バッチファイルのショートカットを C:\ccc\each7z.lnk
に作った場合を考える。
ショートカットには作業フォルダを設定でき、初期値として each7z.bat
のある C:\aaa
が入る。このままショートカットにD&Dした場合、圧縮ファイルは C:\aaa
に作成される。
each7z.lnk
を右クリック→プロパティから、作業フォルダの欄を削除しておくと、each7z.bat
にD&Dした時と同様、D&D元のフォルダが作業フォルダとなる。