え!? 現在のフォルダ以下にある全ての PNG/GIF 画像のファイル名・拡張子・相対フォルダ名を再帰的に取得して好きな文字列と結合したソート済みテキストを cmd.exe からワンライナーでクリップボードに直接コピー!?!?
出来らあっ!
フォルダ構成
C:\current\ ← 現在の作業フォルダ
┣ sub\
┃ ┣ more\
┃ ┃ ┗ d.png
┃ ┗ a.png
┣ b.gif
┣ c.png
┣ not_image.txt
┗ z.gif
-
*.png
および*.gif
のファイルだけを対象とする。- フォルダそのものや他の拡張子のファイルは対象外。
- ファイルのパスか何かから以下の情報を切り出して、いいかんじのテキストにしたい。
- ファイル名(例:
a
) - 拡張子(例:
.png
) - 相対フォルダ名(例:
sub\
)
- ファイル名(例:
ワンライナー
cmd /Q /V:ON /C "(for /R %I in (*.png *.gif) do ((set here=%~dpI) & (set rel=!here:%CD%=!) & (echo ファイル名「%~nI」、拡張子「%~xI」 … 相対フォルダ「!rel:~1!」)))" | sort | clip
できた。
結果(クリップボード)
ファイル名「a」、拡張子「.png」 … 相対フォルダ「sub\」
ファイル名「b」、拡張子「.gif」 … 相対フォルダ「」
ファイル名「c」、拡張子「.png」 … 相対フォルダ「」
ファイル名「d」、拡張子「.png」 … 相対フォルダ「sub\more\」
ファイル名「z」、拡張子「.gif」 … 相対フォルダ「」
全行の末尾に改行文字があるので、最後は空行。
ということで解説
せっかくなので徹底的に分解していきたい。
とりあえず複数行に戻してみよう。
書き下し文
cmd /Q /V:ON /C "
(
for /R %I in (*.png *.gif) do (
(
set here=%~dpI
) & (
set rel=!here:%CD%=!
) & (
echo ファイル名「%~nI」、拡張子「%~xI」 … 相対フォルダ「!rel:~1!」
)
)
)
" | sort | clip
うーん、シンタックスハイライトが仕事できない…。
大部分が文字列として渡されてるから仕方無し。
では、個別の解説(という名の備忘録)へ。
※ 以下、特にパスの取得については全て C:\current\sub\a.png
を例として解説する。
例には必ずこの注釈1を付けておくのでわかると思う。
あと、変数は %var%
みたいに斜体で示す。何となく。
cmd /Q /V:ON /C "なんやかんや"
なんやかんや
の処理を cmd.exe の別インスタンスで実行する。
-
/Q
:実行されるコマンド行自身を出力しない。"Quiet" 。- バッチファイルを書く時には
@echo off
でお馴染みのやつ。大事。 - これを指定しないと、出力テキストに
C:\current>((set here=C:\current\sub\ ) & (set rel=!here:C:\current=! ) & (echo ファイル名「a」、拡張子「.png」 … 相対フォルダ「!rel:~1!」 ) )
1 みたいなコマンド行自身も含まれてしまってえらいことになるので、黙っててもらう。- なお、今回は
do (〜)
の箇所をdo @(〜)
としても同じ結果になる。
- なお、今回は
- バッチファイルを書く時には
-
/V:ON
:遅延環境変数の展開を有効化する。"Variable" 。- バッチファイルでは
setlocal enabledelayedexpansion
でお馴染みのやつ。ちょー大事。 - cmd.exe は、デフォルトでは変数の「展開」のタイミングが各処理のそれと並行しないことがある。特にワンライナーでは、コマンド同士を
&
等で繋ぐ都合のせいか、その制限が更に厳しい。
この仕様についてはググれば怨嗟2の声がいくらでも出てくるが、とにかくこの遅延なんちゃらを有効化すると、%var%
の他に!var!
という記法の変数展開が使えるようになる。- なお、
%TMP%
みたいな既に値を持っている環境変数とかは普通に使える。
- なお、
- 今回、処理全体を
cmd
でわざわざ囲んでいる大きな理由はこれ。
**忌々しい。**←怨嗟の声
- バッチファイルでは
-
/C "なんやかんや"
:なんやかんや
を実行して停止する。"Carry out" 。- 停止しない
/K
というのもあるが、今回は停止してくれないと次のsort
やclip
にデータが渡らないので、大人しく死んでもらう。
- 停止しない
書き下し文(cmd
内)
cmd
に文字列として渡された実行内容を改めて書き下すと、この通り。
(
for /R %I in (*.png *.gif) do (
(
set here=%~dpI
) & (
set rel=!here:%CD%=!
) & (
echo ファイル名「%~nI」、拡張子「%~xI」 … 相対フォルダ「!rel:~1!」
)
)
)
ありがとうシンタックスハイライト。
for /R %I in (*.png *.gif) do なんか
in (*.png *.gif)
を1件ずつ読み込んで %I
に代入し、do なんか
内で好きなコマンドとして実行する。
-
/R
:in ()
としてファイルセットを受け付け、条件に該当するファイルを再帰的に検索する。"Recursive" 。 -
%I
:見つかったファイルのフルパス(たぶん)が代入される変数。- 変数名には1文字しか使えないが、別に
%I
じゃなくても良い。
仕様が妙に柔軟で、%_
とか%1
とかでもいける。 -
for
の変数参照は、上述した遅延なんちゃらを利用しなくても普通に使える。!I
などとしてはいけない。 -
※ 変数
%I
をコマンド直打ちでなくバッチファイルの中に記述する場合は、パーセント記号を重ねて%%I
などと指定すること。
- 変数名には1文字しか使えないが、別に
-
in (*.png *.gif)
:ファイルセット。要はワイルドカードで指定するファイル名。- 今回のような複数条件は、単に半角スペース区切りで並べれば良い。
-
do なんか
:該当ファイルが見つかる度になんか
を実行する。- 実行内容では変数
%I
を利用でき、更にバッチファイルにおける%~dp0
等でお馴染みの引数置換構文をこの変数に適用できる。使う場合は恐らく~
が必須。
今回も3種類ぐらい使うが、詳細は追い追い。 -
※ 変数
%I
をコマンド直打ちでなくバッチファイルの中に記述する場合は、パーセント記号を重ねて%%I
などと指定すること。ダブルチェックヨシ!
- 実行内容では変数
(set here=%~dpI)
各ファイルがあるフォルダのフルパスを here
に代入する。
-
(
〜)
:コマンドをそこで区切ってひとまとめにする。- この重要性の話は余談にて。
-
set なまえ=あたい
:変数なまえ
を宣言し、あたい
を代入する。 -
here
:宣言した変数。後で使う。- 宣言時は、変数名に
%
とか!
とかを付けてはいけない。
- 宣言時は、変数名に
-
%~dpI
:引数置換構文。ファイル%I
が置かれているフォルダまでのフルパスC:\current\sub\
1 。
& (set rel=!here:%CD%=!)
動的環境変数 %CD%
を利用して !here!
から相対パス名を取得し、変数 rel
に代入する。
-
&
:1行に複数のコマンドを記述する。ワンライナーの最高の友達。 -
(
〜)
、set なまえ=あたい
:上述。 -
rel
:宣言した変数。後で使う。 -
!here:%CD%=!
:これ、書いてみたら通っちゃって**「え、いいの!?」**となったようなやつなので、どう説明すべきか…。-
!here!
:さっき宣言した変数。ファイルのあるフォルダまでのフルパスC:\current\sub\
1 を持つ。- 使う時にはこのように
!
や%
で囲う。
- 使う時にはこのように
-
%CD%
:作業フォルダのフルパスC:\current
を勝手に持っている動的環境変数。- 末尾にフォルダ区切り文字
\
を含まない。
- 末尾にフォルダ区切り文字
-
%へんすう:ア=イ%
:変数%へんすう%
が持つ文字列中のア
を全てイ
に置換した文字列を返す記法。- 例えば
echo %CD:c=Z%
というコマンドはz:\zurrent
を出力する。大文字・小文字は無視するっぽい。
あるいはecho %CD:t=%
とすれば、空文字への置換(=文字列の削除)が行われて、:\urrent
を出力する。
- 例えば
-
ということで、まぁ最後のやつは、
「!here!
の中の %CD%
と一致する箇所を空文字列に置換する」
=「C:\current\sub\
1 から C:\current
を削除する」
=「相対フォルダ名 \sub\
1 を取得する」
という処理になる。
…なるが、cmd.exe においてそんな風に変数を変数で置換するのは、本来ならもっと困難を伴う。
@echo off
set var=c
echo 元 : %CD%
echo 失敗: %CD:%var%=z%
echo 失敗: %%CD:%var%=z%%
call echo 成功: %%CD:%var%=z%%
pause
元 : C:\current
失敗: var
失敗: %CD:c=z%
成功: z:\zurrent
続行するには何かキーを押してください . . .
具体的には call
と二重の %
が要る。なんだそれ。
今回そういう困難とご挨拶せずに済んだのは、遅延なんちゃらである !here!
とそうではない %CD%
との性質の違い、もっと言えば変数としての展開タイミングの違いによるものだろう。たぶん。
& (echo ファイル名「%~nI」、拡張子「%~xI」 … 相対フォルダ「!rel:~1!」)
今まで準備してきた変数を用いて、望むテキストを標準出力する。
-
&
、(
〜)
:上述。 -
echo
:メッセージを標準出力する。- 最終的に得られるテキストを直接生み出すのはこいつ。
そういう意味では最重要コマンドだろう。
- 最終的に得られるテキストを直接生み出すのはこいつ。
-
%~nI
:引数置換構文。ファイル%I
の拡張子抜きファイル名a
1 。- **※ 変数
%I
をコマンド直打ちでなくバッチファイルの中に記述する場合は、パーセント記号を重ねて%%I
などと指定すること。**クアドラプルチェックヨシ!!!!
- **※ 変数
-
%~xI
:引数置換構文。ファイル%I
の拡張子.png
1 。- ※ 変 数
%I
を コ マ ン ド 直 打 ち で な く バ ッ チ フ ァ イ ル の 中 に 記 述 す る 場 合 は 、 パ ー セ ン ト 記 号 を 重 ね て%%I
な ど と 指 定 す る こ と 。 ク イ ン タ プ ル チ ェ ッ ク で 今 日 も 一 日 ご 安 全 に ! ! ! ! ! ! ! ! ! !
- ※ 変 数
-
!rel:~1!
:これはまぁ、さっきの置換記法よりは難しくない。-
!rel!
:さっき宣言した変数。ファイルのある相対フォルダ名\sub\
1 を持つ。 -
%へんすう:~N%
:先頭を0文字目として、変数%へんすう%
が持つ文字列のN
文字目以降を切り出して返す記法。- 例えば
echo %CD:~1%
というコマンドは:\current
を出力する。
- 例えば
-
ということで、最後のやつは
「相対フォルダ名 \sub\
1 の先頭1文字を削除した文字列 sub\
1」
を表す。
先頭をなぜ消すかって、これをやらないとファイルが作業フォルダ直下にある場合に相対フォルダ名が \
になるのがキモいので…。
そんなら !rel!
の宣言代入時に消しとけよって感じになるが、実はそこには大いなる罠が待ち受けている。
@echo off
echo 通常の変数の場合
set s=ABC
set s1=%s:~1%
set s99=%s:~99%
REM ↑たった3文字しか無い元文字列の、先頭99文字を削除。
REM こういうオーバーキルをした場合は空文字列が返る。
echo s「%s%」、s1「%s1%」、s99「%s99%」
echo 遅延環境変数の場合
cmd /Q /V:ON /C "(set s=ABC) & (set s1=!s:~1!) & (set s99=!s:~99!) & (echo s「!s!」、s1「!s1!」、s99「!s99!」)"
pause
通常の変数の場合
s「ABC」、s1「BC」、s99「」
遅延環境変数の場合
s「ABC」、s1「BC」、s99「!s99!」
続行するには何かキーを押してください . . .
遅延環境変数の展開においては、変数に空文字列が直接代入されているとなんか上手くいかんらしい。いかんならしゃーない。
これを防ぐために、変数 !rel!
にはあえて無駄な1つの頭文字を持たせておいて、いざ表示という段においてのみそれを必ず1文字削る、という手順を経ている。
もし本当に要らないなら、宣言と代入の時点で set rel=!here:%CD%\=!
3 とすれば容易に消しておけるのだ。
もう一息
cmd /Q /V:ON /C "なんやかんや" | sort | clip
(
)
が生い茂り !
%
が降り注ぐ、"なんやかんや"
の縄張りを今抜けた。
ゴールは目と鼻の先だ。
あれやこれや | sort
あれやこれや
の処理が一通り済んだら、その内容をソートして標準出力する。
-
あれやこれや
:行う処理。 -
|
:標準出力を次のコマンドにパイプする(渡す)。 -
sort
:受けたテキストの行を辞書順に並べ替えて標準出力する。
どうってことはない。
てんやわんや | clip
てんやわんや
の処理が一通り済んだら、その内容をクリップボードにコピーする。
-
てんやわんや
:行う処理。 -
|
:上述。 -
clip
:受けたテキストをクリップボードにコピーする。
どうってことなさすぎる。
てなわけで完了!!!!!!!
まとめ
C:\current\ ← 現在の作業フォルダ
┣ sub\
┃ ┣ more\
┃ ┃ ┗ d.png
┃ ┗ a.png
┣ b.gif
┣ c.png
┣ not_image.txt
┗ z.gif
ファイル名「a」、拡張子「.png」 … 相対フォルダ「sub\」
ファイル名「b」、拡張子「.gif」 … 相対フォルダ「」
ファイル名「c」、拡張子「.png」 … 相対フォルダ「」
ファイル名「d」、拡張子「.png」 … 相対フォルダ「sub\more\」
ファイル名「z」、拡張子「.gif」 … 相対フォルダ「」
cmd /Q /V:ON /C "(for /R %I in (*.png *.gif) do ((set here=%~dpI) & (set rel=!here:%CD%=!) & (echo ファイル名「%~nI」、拡張子「%~xI」 … 相対フォルダ「!rel:~1!」)))" | sort | clip
cmd /Q /V:ON /C "
(
for /R %I in (*.png *.gif) do (
(
set here=%~dpI
) & (
set rel=!here:%CD%=!
) & (
echo ファイル名「%~nI」、拡張子「%~xI」 … 相対フォルダ「!rel:~1!」
)
)
)
" | sort | clip
めでたし。
余談
以下余談。
心の声(パスに半角スペースや %
や !
が交ざってても大丈夫なの…?)
C:\cu !r!r%e% nt\ ← 現在の作業フォルダ
┣ %CD% !CD!\
┃ ┣ !rel! %rel%\
┃ ┃ ┗ dracula %Is !here!.png
┃ ┗ a縺薙s縺ォ縺。縺ッ.png
┣ b.gif .exe
┣ c ,.'`+-=^~_()[]{};!#$%&@.png
┣ not_image.txt
┗ z%% o%m%b%%Ie.gif
いっけなーい🔪 殺意殺意💦
ある日突然、平和なディレクトリに悪意の塊が攻めてきてもう大変💦
一体私達、これからどうなっちゃうの〜😭😭!?
ファイル名「a縺薙s縺ォ縺。縺ッ」、拡張子「.png」 … 相対フォルダ「%CD% \」
ファイル名「c ,.'`+-=~_()[]{};!#$%&@」、拡張子「.png」 … 相対フォルダ「」
ファイル名「dracula %Is C:\cu !r!r%e% nt\%CD% C:\cu !r!r%e% nt\\%CD% \ %rel%\」、拡張子「.png」 … 相対フォルダ「%CD% \\%CD% \ %rel%\」
ファイル名「z%% o%m%b%%Ie」、拡張子「.gif」 … 相対フォルダ「」
答:ダメ。
大丈夫な例
-
a縺薙s縺ォ縺。縺ッ
- aのファイル名
-
c ,.'``+-=~_()[]{};!#$%&@
- cのファイル名
-
z%% o%m%b%%Ie
- zのファイル名
-
.png
- a、c、dの拡張子
-
.gif
- zの拡張子
※ bは .exe
面に堕ちたのでヒットしない。
ダメな例
-
%CD% !CD!\
→%CD% \
- aの相対フォルダ名
-
dracula %Is !here!.png
→dracula %Is C:\cu !r!r%e% nt\%CD% C:\cu !r!r%e% nt\\%CD% \ %rel%\
- dのファイル名
-
%CD% !CD!\!rel! %rel%\
→%CD% \\%CD% \ %rel%\
- dの相対フォルダ名
半角スペースとか単なる変な記号とか %
の変数名とかはやりすごせても、!
の方の変数名(しかも実在するやつ)を突かれちゃうと無理な模様。
バッチファイルだったら setlocal
の範囲を最低限にすることで多少はコントロールできるらしいんだけど、ワンライナーだと多分、さすがにどうしようもないかな……。
心の声(ルート直下にあるファイルについては … 相対フォルダ「」
なんて表示自体要らないのでは…?)
フリー素材です pic.twitter.com/nW2NmVYLPa
— 森の子リスのミーコの大冒険 (@Phroneris) December 6, 2018
cmd /Q /V:ON /C "(for /R %I in (*.png *.gif) do ((set here=%~dpI) & (if !here!==%CD%\ (set rel=\) else (set rel=\ … 相対フォルダ「!here:%CD%\=!」)) & (echo ファイル名「%~nI」、拡張子「%~xI」!rel:~1!)))" | sort | clip
cmd /Q /V:ON /C "
(
for /R %I in (*.png *.gif) do (
(
set here=%~dpI
) & (
if !here!==%CD%\ (set rel=\) else (set rel=\ … 相対フォルダ「!here:%CD%\=!」)
) & (
echo ファイル名「%~nI」、拡張子「%~xI」!rel:~1!
)
)
)
" | sort | clip
ファイル名「a」、拡張子「.png」 … 相対フォルダ「sub\」
ファイル名「b」、拡張子「.gif」
ファイル名「c」、拡張子「.png」
ファイル名「d」、拡張子「.png」 … 相対フォルダ「sub\more\」
ファイル名「z」、拡張子「.gif」
if
文最高!
心の声(cmd "なんやかんや"
の中に更なる "
があったら…?)
うるせえなこいつ…。
今回は関係無いけど、一応。
もし cmd
の実行内容が入れ子のダブルクォーテーションを持っていても、かしこい cmd.exe は実行内容の最初の "
と最後 の "
の2つだけを削除してから実行する(少なくとも1段階の入れ子を許容する)ので問題にならない。
cmd /C "echo Call me "Taxi"."
REM > Call me "Taxi".
かしこい。
cmd "なんやかんや"
で処理全体を囲むもう1つの理由
大きな理由は遅延なんちゃらのため、と既に述べた。
実はもう1つ小さな理由があり、それは クリップボードにコピーした時の各行末のスペース除去とコード自体の見やすさを両立するため。
ここにコマンドがあるじゃろ。
echo val1 val2 | clip
これを実行すると、クリップボードにコピーされるテキストはこうじゃ。
val1[sp]val2[sp]
…見ての通り、末尾に余計なスペースがくっつく。
目的によってはそれを許容できることもあるが、今回はなんかキモいからお断り申し上げたい。
なんでこうなるのかというと、多分 echo
は末尾のスペースをも文字列の一部として貪欲に捕捉してしまうのだろう。
故に、こう書けば一応は解決する。
echo val1 val2| clip
REM > val1[sp]val2
…が、いや今度はコード側がキモくない???
ワンライナーはただでさえ呪文のようになりがち。
それを少しでも見やすくするために、コマンド同士をどうのこうのする |
とか &
とか (カッコ)
とかの前後にはできればスペースを挟んで記述したい、というのが個人的な願い。
cmd.exe はほんとそういうとこが**忌々しい。**←怨嗟の声
ということで試行錯誤すると、こんな風になった。
REM *commands* *results*
echo 1 test | clip REM > 1[sp]test[sp]
echo 2 test| clip REM > 2[sp]test
(echo 3 test) | clip REM > 3[sp]test[sp]
(echo 4 test)| clip REM > 4[sp]test[sp]
cmd /C "echo 5 test" | clip REM > 5[sp]test[sp]
cmd /C "echo 6 test"| clip REM > 6[sp]test
cmd /C "(echo 7 test)" | clip REM > 7[sp]test
cmd /C "(echo 8 test)"| clip REM > 8[sp]test
見ての通り、結果のスペース除去とコードのスペース空けを両立できるのは7番目の記法のみとなる。
特に (カッコ)
の発見の意義は大きく、このおかげで今回のワンライナーは (カッコ)
まみれとなったのであった。
ちなみに
そんなに頑張らなくても、3番目の記法と適当な一時ファイルを経由すれば、末尾のスペースは勝手に消える。
(echo val1 val2) > %TMP%\tmp.txt & clip < %TMP%\tmp.txt & del %TMP%\tmp.txt
REM > val1[sp]val2
うるせえ!!! クリップボードに直接渡せるのがロマンなんだよ!!!!!!
…そういうことにしておいてください。
っていうかなんでファイルか否かで出力差が出るんだよ……何なんだよほんと……。
for /R 〜
の代替手段
今回は一番短い for /R 〜
を採用したが、他にもある。
-
for /F "delims=" %I in ('dir /A-D/B/S *.png *.gif') do なんか
- 機能が多いので、やりたいことが変わっても柔軟に対応しやすい。
- その分めんどい。
- ファイルではなくフォルダだけを得ようとした場合、以下の通り、今回の手法とは少し違う結果になる。
- 機能が多いので、やりたいことが変わっても柔軟に対応しやすい。
C:\current> for /R %I in (.) do @echo %I
C:\current\.
C:\current\sub\.
C:\current\sub\more\.
C:\current> for /F "delims=" %I in ('dir /A:D/B/S') do @echo %I
C:\current\sub
C:\current\sub\more
-
for /F "delims=" %I in ('where /R %CD% *.png *.gif') do なんか
- 単にファイルだけを検索してそのフルパスだけを返すので、わかりやすい。
- その分自由度が低い。
少なくとも、フォルダ名を得ることはできない。
- その分自由度が低い。
- 単にファイルだけを検索してそのフルパスだけを返すので、わかりやすい。
他には forfiles
というのもあり、こいつは相対フォルダ名もデフォルトで取得できるので可能性は感じる。
しかし、触った感じでは以下のように自由以上の不自由に直面したのでやめた。
- 複数条件が指定不能。
- 出力が何もかもダブルクォーテーションで囲まれている。
-
echo
の出力内容にスペースが挟まるだけで問題が起こる。
その他
-
cmd
等の各種コマンド、/Q
等の各種パラメーター、%~dp0
等の引数置換構文、そして変数の命名では、大文字・小文字を区別しない。
ただし、for
の1文字変数だけはそれを区別する。なんで…?
C:\current>set a=12345
C:\current>eChO %A%
12345
C:\current>FOR /r %I in (*.gif) DO @ECHO %~NXI %~NXi
b.gif %~NXi
z.gif %~NXi
- コマンドをバッチファイルで試す時は UTF-8 で保存しない。(2敗)
- 筆者環境:Windows 7 Professional 64-bit
参考
† 圧倒的感謝 †
Qiita
-
上司「このフォルダーにあるファイルのリスト作って」 > #Q1.任意のフォルダーにあるファイルの一覧を作成 - Qiita
- これのお陰でシンプルな
for /R 〜 in (*.*)
に辿り着けた。MVP。
- これのお陰でシンプルな
-
Windows バッチファイルで格納先フォルダ名を取得 - Qiita
-
%CD%
なる動的環境変数をここで初めて知った。
最初はそのまんまこの方法でサブフォルダ名を取得しようとしていたが、いっそ%CD%
で丸ごと置換しちゃえばええやんと思い付き、やってみたら成功したのでヨシ!
-
-
バッチファイルでの試行錯誤を回避するためのメモ > #変数を使用した文字列置換 - Qiita
- あわやヨクナシ!
今回はなんか回避してたけど、まぁ回避できない時は改めてこちらの方法でやれば良いだけのこと。
- あわやヨクナシ!
Stack Overflow
-
Batch: Pipe command output to variable and compare - Stack Overflow
- 直接は活用しなかったが、cmd.exe に何ができて何ができないのかがまだよくわかってない時に、ワンライナーでの変数利用に関する「何ができないのか」の一部を示してくれた。
-
CMD string variable multi-line output without additional spaces and carriage returns - Stack Overflow
- これも直接活用したかというとアレだが、
| clip
の行末スペースに困る人が他にもいて、それを一時ファイル無しで解決してる人もちゃんといる、という事実が光になった。
- これも直接活用したかというとアレだが、
個人サイト系、他
-
コマンドプロンプト - 忘れるので
- 多分一番最初に見つけた方法がこの
for /F 〜 in ('dir /B/A-D *.*')
だった。
この記事に限らず、ググればググるほどこの方法があちこちで見つかったので、最初はこれが唯一の解だと思っていた。
- 多分一番最初に見つけた方法がこの
-
コマンドプロンプトのワンライナーでズンドコキヨシ - くんすとの備忘録
- ワンライナーでの変数使用例として、普通にためになってしまった。
-
BATファイルで文字列の切り出し - アプ研
- 単純にして明快。文字列切り出しの基礎の全てがここにある。
-
cmd /?
等のヘルプ機能- 1次ソース万歳。
おわり