2011-11-27
■[Twitter]ファイル名に記号が含まれるか判定する(ファイルのドロップ)
@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
■[hatena]FOR文やIF文で変数の中身が消える? (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% が 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][petitcom]DSiウェアのプチコンについて
プチコンとは
DSiで動くBASICインタプリタ環境です。マイコン世代には涙ものです。
詳しくはプチコンを取り上げている各ページをご覧ください。
おっさんホイホイ! DSiで動くBASIC「プチコン」 : ギズモード・ジャパン
たぶん今こそBASIC ニンテンドーDSiでBASICが動く「プチコン」 - ITmedia ニュース
【PC Watch】 スマイルブーム、ニンテンドーDS用BASIC処理系「プチコン」
DSiウェア『プチコン』でプログラミングが楽しめる - ファミ通.com
何がすごいか
なんと言っても、ソースリストをプチプチとタッチパネル上のキーボードで手打ちしないとソフトで遊べません。インターネットやSDカードからテキストを読み込む手段はありません。
打ち込んだリストはDSのメモリ上にファイル名を指定して保存/読み出しすることができます。唯一受け渡し可能なのが、DSiを並べてWi-Fiでの転送。友達とのプログラム交換ですね。マニアックな子ども達の間でソース交換が流行るはず!と予測しておきます。
古き良き時代のBASICと違うところ
いろいろあるのですが、特徴的なところを挙げておきます。
| 行番号がない | 行番号の代わりにラベルを使います |
| 比較演算子で"="や"<>"を使わない | "=="や"!="だそうです。今風ですね |
| IF文にELSEがない | 少し厳しいですね |
| INT関数がない | 計算式で逃げることになるのかな? |
| INSTR関数がない | 地味につらいですね |
| PLAY文(MML)がない | BEEP文とBGM文を駆使して対応ですね |
逆にDSのタッチパネルやボタンの取得ができたり、スプライトやキャラクタの定義ができたりします。すごい!
購入編は次のエントリーで!