バッチもん研究所 blog このページをアンテナに追加 RSSフィード Twitter

2011-11-27

[]ファイル名に記号が含まれるか判定する(ファイルドロップ

ツイッター検索でみつけたツイート

あなたの天然記念物さんのツイート

@yrntrlmnmnt: 【挑戦者求む】「記号入りファイル名!@#$%^&()_+~-=`{}[]'.txt」(@は半角に読み替え)という名前のファイルドロップして、ファイル名に記号があることを判定できるバッチファイル存在するか?

普通に"%~nx1"で取り出そうとしたらうまくいかなかった。

イコール "=" が引数の区切りとして扱われてしまうみたい。しかもファイルドロップしたときだけうまくいかないという不思議挙動

そこで "%*" をつかって、for /f "delims=" %%F で取り出したあと、%%~nxF を使う方法にしてみたらうまくファイル名だけ取り出せた。

あとは、findstr で検索すればなんとかなるはず。という感じでつくったのがこれ。

echo off
for /f "delims=" %%F in ('echo %*') do echo "%%~nxF">$$tmp.txt
:pause
findstr /R "[-!@#$%^&()_+~=`{}[\]']" $$tmp.txt
if errorlevel 1 goto notfound
echo 記号がありました
goto end
:notfound
echo 記号はありませんでした

:end
pause
del $$tmp.txt

一通り試してみたけど、うまく動いているかな?

ドロップするファイルのパスによる変化に対応するよう一部修正しました。

2011-07-09

[]FOR文やIF文で変数の中身が消える? (DOS変数の代入)

気になった記事が。


DOSの変数の代入 - 揮発性のメモ


    FOR /F "tokens=1" %%i IN (hoge.txt) DO (
        ECHO NAME=%%i
        SET NAME=%%i
        ECHO NAME=%NAME%
    )
NAME=aaa
NAME=

変数に代入すると変数の中身が消える。なんだろうこれ。

http://d.hatena.ne.jp/iww/20110617/dos

変数に代入すると変数の中身が消える。なんだろうこれ。

いえいえ、変数の中身は消えませんよ。

for文のdo以降を()でくくられていますが、この複文内の環境変数はfor文が実行される直前に、すべて環境変数の中身に展開されてから実行されます。

for文が実行されているループの都度%NAME%が参照されて変化するわけではありません。

つまり、

    FOR /F "tokens=1" %%i IN (hoge.txt) DO (
        ECHO NAME=%%i
        SET NAME=%%i
        ECHO NAME=%NAME%
    )

でFOR文実行時に環境変数NAMEが未定義(空)だった場合は

    FOR /F "tokens=1" %%i IN (hoge.txt) DO (
        ECHO NAME=%%i
        SET NAME=%%i
        ECHO NAME=          ←%NAME%の値に展開済み
    )

を実行しているのと同じです。

詳しくは、set /? で出てくるヘルプ

「最後に、遅延環境変数の展開が追加されました。」

の行以降の説明を以下に転記しますので読んでみてください。

最後に、遅延環境変数の展開が追加されました。このサポートは常に既定で

無効になっていますが、CMD.EXE の /V: のコマンド ライン スイッチを使

って有効または無効にできます。

CMD /? を参照してください。

遅延環境変数の展開は、実行時ではなく、テキスト行を読み取るときに展開

されるという現在の制限を避けるために役立ちます。

次の例は即時変数展開の問題を説明しています。

set VAR=before

if "%VAR%" == "before" (

set VAR=after;

if "%VAR%" == "after" @echo If you see this, it worked

)

この例は、論理的には IF 文が別の IF 文の本体に含まれる複合文なので、

両方の IF 文の %VAR% が、最初の IF 文を読み取ったときに展開されます。

このため、メッセージは決して表示されません。

複合文の中の IF では "before" と "after" が比較され、

決して等しくはなりません。

同様に次の例も期待したようには動作しません。

set LIST=

for %i in (*) do set LIST=%LIST% %i

echo %LIST%

この例では、現在のディレクトリファイルの一覧は作成されず、代わりに最後

に見つけられたファイルが LIST 変数に設定されます。

これは %LIST% が FOR 文が読み取られるとき、

一度だけ展開され、そのときは LIST 変数が空だからです。

つまり、実際に実行されている FOR ループ

for %i in (*) do set LIST= %i

で、LIST に最後に見つけられたファイルを設定し続けているだけです。

遅延環境変数の展開では、実行時に環境変数を展開するために異なった文字

(感嘆符) を使うことができます。

遅延環境変数の展開が有効な場合、上記の

例は次のように書くと意図したように動作します。

set VAR=before

if "%VAR%" == "before" (

set VAR=after

if "!VAR!" == "after" @echo If you see this, it worked

)

set LIST=

for %i in (*) do set LIST=!LIST! %i

echo %LIST%

なお!をつかった遅延変数展開は

「CMD.EXE の /V: のコマンド ライン スイッチを使って有効」

にしなくても

setlocal ENABLEDELAYEDEXPANSION

で有効にできます。詳しくは setlocal /? をご覧ください。

ようするに、FOR文の中ではSETが動作しないっぽい。なるほど。ふざけんな。

IF文とか、FOR文で使う ( ) の中だと、SETが動作しないことがある。

http://d.hatena.ne.jp/iww/20110617/dos

上記のようにSETはちゃんと動作してます。

複文はその行を実行するときに環境変数を展開するので注意が必要です。IF文とかに()を使うときも同様ですね。

というわけで、私は()をつかった複文はあえて使わないことが多いです。

2011-03-10

[][][]DSiウェアのプチコンについて

プチコンとは

DSiで動くBASICインタプリタ環境です。マイコン世代には涙ものです。

詳しくはプチコンを取り上げている各ページをご覧ください。

プチコン

プチコン

おっさんホイホイ! DSiで動くBASIC「プチコン」 : ギズモード・ジャパン

たぶん今こそBASIC ニンテンドーDSiでBASICが動く「プチコン」 - ITmedia ニュース

【PC Watch】 スマイルブーム、ニンテンドーDS用BASIC処理系「プチコン」

DSiウェア『プチコン』でプログラミングが楽しめる - ファミ通.com

[N] 「プチコン」ニンテンドーDSi用BASIC


何がすごいか

なんと言っても、ソースリストプチプチタッチパネル上のキーボードで手打ちしないとソフトで遊べません。インターネットSDカードからテキストを読み込む手段はありません。

打ち込んだリストDSメモリ上にファイル名を指定して保存/読み出しすることができます。唯一受け渡し可能なのが、DSiを並べてWi-Fiでの転送。友達とのプログラム交換ですね。マニアック子ども達の間でソース交換が流行るはず!と予測しておきます。


古き良き時代のBASICと違うところ

いろいろあるのですが、特徴的なところを挙げておきます。

行番号がない行番号の代わりにラベルを使います
比較演算子で"="や"<>"を使わない"=="や"!="だそうです。今風ですね
IF文にELSEがない少し厳しいですね
INT関数がない計算式で逃げることになるのかな?
INSTR関数がない地味につらいですね
PLAY文(MML)がないBEEP文とBGM文を駆使して対応ですね

逆にDSタッチパネルやボタンの取得ができたり、スプライトやキャラクタの定義ができたりします。すごい!



購入編は次のエントリーで!