ファイル名の拡張子の直前のドット以外のドットを置換するバッチファイル

以前の記事にコメントをいただいてました。

ファイル名の置換(ファイル名の一部文字を別の文字に置き換える) - バッチもん研究所 blogのコメント欄

sぱ 2017/01/18 19:13

便利に使わせていただいてます
ファイル名の拡張子の.だけ消去せずに その前の.を置換する方法はありますか?

call :sub で呼び出した先の引数は%1で呼び出せますが、ファイル名の拡張子と拡張子を除くファイル名に分けるのに
%~n1
%~x1
が使えます。
例えば sample1.1.3.txt なら
%~n1 は sample1.1.3
%~x1 は .txt
が入ります。

この %~n1 を置換の対象にすればいいでしょう。
以下はファイルの"."(ドット)を"_"(アンダーバー)に置換するサンプルです。

echo off
for /F "delims=" %%F in ('dir /b') do call :sub "%%F"
exit /b

:sub
set fname=%~n1
set fname=%fname:.=_%
ren "%~1" "%fname%%~x1"
goto :EOF

iOS7でユーザ辞書が表示されない状況になったときに試す復旧方法(暫定公開版)

【はじめに】

自分のユーザ辞書はいつからかおかしくなって、以下のような症状がでていました。

  • ちまたにあるユーザ辞書がおかしくなったときの手順(iCloudをオフにする、再起動する、自動修正、スペルチェックをオフにするなど)ではどうにもならない
  • 設定アプリ-[一般]-[キーボード]を選ぶと固まる。しばらくするとユーザ辞書が表示される。
  • ユーザ辞書の編集(削除)するたびに固まる(自分は20秒ぐらい)。
  • ユーザ辞書の読みをいれても候補に出てこない。しばらくして(読み)+1文字を入力すると単語が出てくることがある。

例)単語:(;o;) よみ:なき で登録していたとして、
「なき」と入力しても出てこないが、しばらくして「なきは」と入れると「(;o;)は」とでてくることがある。時間がかかるのと追加する1文字が一定していない。

  • フリック左下の顔文字ボタン ^_^ を押しても顔文字の登録単語が全く出てこない
  • 設定アプリ-[一般]-[情報]-[診断/使用状況]-[診断データと使用状況データ]でclashレポートが文字入力のたびに作られている。kbdプロセスがクラッシュしている。

こんな状態を改善すべくApple サポートコミュニティや色々な人のブログからヒントをいただき以下の手順で何とか復旧しました。

本手順は、iTunesで作成されたバックアップを書き換えるという方法ですので、最悪バックアップからの復元が自分で出来る人を対象としています。とりあえず画面のハードコピーなどを省略して書いていますので、手取り足取りの手順がないと不安な人は少し待ったほうが良いかも。

【この手順で復旧できる可能性について】

  • 過去にiOSバージョンアップなどでバックアップが残っている人
  • 過去のバックアップの時にユーザ辞書が正常でその時点の辞書にもどってもOKな人
  • Windowsユーザ(対象ソフトのMac版もあります。同じ方法でMacでも復旧できた人はぜひ教えてください)

【対象アプリのインストール】

使用するアプリは以下の2つです。
iBackupBot
iBackupBot - iTunes Backup Manager for iPhone, iPod Touch, iPad
PupSQLite
Vector PupSQLiteの詳細情報 : Vector ソフトを探す!
窓の杜 「PupSQLite」SQLiteのデータベースをGUIで操作できる高機能管理ソフト - 窓の杜
→作者のページ Pup's Atelier-Software

iBackupBotでバックアップのなかからユーザ辞書のファイルを取り出します
PupSQLiteではユーザ辞書の中身を確認します。

【まずはバックアップ】

iTunesiPhoneを接続して、iPhoneの「概要」にある「手動でバックアップ/復元」の[今すぐバックアップ]で作業前のバックアップをとっておきます。

【バックアップの確認】

iBackupBotをインストールして起動すると、iTunesでとったバックアップの一覧が表示されます。
過去のバックアップとともに,先ほどとったバックアップも表示されるはずです。
まずは最新のバックアップを選択して右クリックで Duplicateでバックアップのバックアップとります(保存先のフォルダを適当に指定して)。失敗したときこのバックアップのバックアップから復元することになるとおもいます(自分は幸いにも使いませんでした)。
これはかなり時間がかかります(本体容量にもよると思います。自分は3〜40分かかりました)。

Duplicate蛾終わったら、バックアップファイル一覧から先ほどとったバックアップ(日付と時間で判断)の中身をツリー表示から展開していきます。

System Files
  -HomeDomain
   -Library
     -Keyboad
       -CoreDataUbiquitySupport
         -mobile〜XXXXXXXXX(何かのID??)
           -UserDictionary

この中にフォルダが複数あり自分の場合は
3516xxxx-xxxx-xxxx(以下略)
D05exxxx-xxxx-xxxx(以下略)
EB79xxxx-xxxx-xxxx(以下略)
local
の4つでした。
さらにその階層を開いていくと、storeというフォルダに
CloudUserDictionary.sqlite
というファイルが入っています(入っていないフォルダもあるみたい)
とりあえずこのファイルが肥大化しているはずです。
通常ユーザ辞書なら大きくても数十〜数百kBだとおもいますが、自分の場合は18MBとか15MBというものがありました。とりあえずそれぞれのフォルダの
CloudUserDictionary.sqlite
を抽出します。
iBackBotの右側のウインドでCloudUserDictionary.sqliteを選択し、上にあるExportのボタンを押すと保存するフォルダを聞いてきます。自分の場合は4つあったのでそれぞれのフォルダを作って区別がつくように抽出・保存しました。

【抽出したファイルの確認】※省略してもよい

抽出した CloudUserDictionary.sqliteをPupSQLiteで中身を確認します。
自分の場合は一番大きい18MBのファイルは壊れていて表示できませんでした。
(どうやらこれが原因)

【古いバックアップから正常なファイルの抽出】

自分の古いバックアップは2012年12月のものでした。確かこの頃ならユーザ辞書は正常だったはずです。
このときのバックアップはiOS7以前(iOS6.0.1)ですので格納場所が微妙に違います。

System Files
  -HomeDomain
   -Library
     -Keyboad

このKeyboadフォルダ内に CloudUserDictionary.sqlite がありました。56kBでした。
これを同様にExportで別フォルダに保存します。

【抽出した正常な辞書の確認】

先ほどと同様に古いバックアップから抽出したCloudUserDictionary.sqliteの中身をPupSQLiteで確認すると、見慣れた登録内容がずらり。
[ファイル]-[開く]でCloudUserDictionary.sqliteを開いて、ZUSERDICTIONARYENTRYのテーブルを開くとZPHRASEとZSHORTCUTに単語と読みが並んでいます。

この内容で大丈夫なようなので、PupSQLiteを終了させます。

【正常な辞書で上書き】

もう一度iBackupBotに戻り、最新のバックアップのCloudUserDictionary.sqliteを正常だったCloudUserDictionary.sqliteで上書きします。
自分の場合は4つあったstoreフォルダに移動しImportボタンを押して、正常なCloudUserDictionary.sqliteを指定します。上書きの確認ダイアログに対しYesボタンを押します。(Press Yes to replase the file ;Yesボタンを押すと上書きします)
自分は4つあるうちどれが有効なのかわからなかったのですべて同じファイルで上書き(Import)しました。

iTunesで復元】

復元前にiCloudでの書類とデータの同期をOFFにしておきます。
またiCloutd.comで書類とデータのリセットをしておきます。
iCloud:iCloud の書類とデータサービスをリセットする方法 - Apple サポート

iTunesiPhoneを接続して、同期が始まっても中断してたうえで「手動でバックアップ/復元」からバックアップを復元を選びます。
iPhoneを探す”をオフにするダイアログが出た場合は、指示に従って本体のiPhoneを探すをオフにして復元を進めてください。
バックアップから復元のダイアログで先ほど書き換えたバックアップ(最新のもの)を選択します。

あとは復元手順にしたがって復元します。

自分は復元後、写真の同期で時間がかかりましたが、この方法でユーザ辞書が戻ってきました。
iPhoneの設定アプリ-[一般]-[キーボード]を選んでも固まりませんし、一番したもちゃんとユーザ辞書が表示されるようになりました\(^O^)/
登録内容の追加削除もさくさく!(以前は20秒ぐらい固まっていた)

最後にiPhoneを探すをオフにしたひとはオンに戻しておきましょう。

ユーザ辞書でお困りの方はお試しください。
(ただし自己責任で試してくださいね)

コマンドプロンプトでワイルドカードに想定外のものがヒットする

残念ながら締め切りになってしまってOkwaveには回答できませんでした。

MS-DOSワイルドカードの扱いについて 質問者:treelock


Windows 7環境で、MS-DOSのバッチファイルを作っています。
MS-DOS上でのワイルドカードの扱いに疑問がわいたので質問させてください。

C:\直下に
TEST - 01、TEST - 02、…、TEST - 12
というディレクトリを作ったのですが、
dir *04*
のコマンドで
TEST - 04
TEST - 09
の両方がヒットしてしまいます。

TEST - 04のみヒットすることを期待したのですが、09のほうまでヒットするのはなぜでしょうか。



以下、テキスト貼り付けですが、画面のコピーです。
C:\>dir *04*
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は ****-**** です

C:\ のディレクト

2013/08/03 22:40

TEST - 09 2013/08/03 22:39 TEST - 04 0 個のファイル 0 バイト

MS-DOSのワイルドカードの扱いについて - その他(Windows) 解決済み| 【OKWAVE】

一番わかりやすいのがこの例。

C:\Users\xxx>cd \

C:\>dir *1
 ドライブ C のボリューム ラベルは ABCDEFG004 です
 ボリューム シリアル番号は 1234-ABCD です

 C:\ のディレクトリ

2013/07/20  13:21    <DIR>          Program Files
               0 個のファイル                   0 バイト

ですかね。それで答えは dir /x ってやるとわかると思います。

2013/07/20  13:21    <DIR>          PROGRA~1     Program Files

8.3型式のファイル名にはまらない(文字数や空白が入ってる)場合に、8.3形式のファイルが自動的に割り当てられるんです。
短いファイル名とも言われます。ワイルドカードはこれにも引っかかるんですね。

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

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

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

@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

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

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

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

気になった記事が。


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

    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文とかに()を使うときも同様ですね。

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

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

何がすごいか

なんと言っても、ソースリストをプチプチとタッチパネル上のキーボードで手打ちしないとソフトで遊べません。インターネットやSDカードからテキストを読み込む手段はありません。
打ち込んだリストはDSのメモリ上にファイル名を指定して保存/読み出しすることができます。唯一受け渡し可能なのが、DSiを並べてWi-Fiでの転送。友達とのプログラム交換ですね。マニアックな子ども達の間でソース交換が流行るはず!と予測しておきます。

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

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

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

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



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

配列風変数を比較して処理する事は可能でしょうか?

hycafeさんからバッチファイルで配列を使う(環境変数を使って配列変数風に使う)方法についてのエントリーにコメントをいただきました。

hycafe 2011/02/10 10:38

配列風変数を比較して処理する事は可能でしょうか?

テキストの内容を配列風変数に代入して比較後に処理を実施したいのですが、下記のような例でうまく動きません。

***********************
REM テキストの内容を取得します。
REM テキスト内容は「リンゴ」、「バナナ」とします。
for /f %%i in (%Windir%test.txt) do @call :add %%i

:add
set x[%i%]=%1
REM 配列の比較     
call if %%x[%i%]%%==リンゴ (
echo 赤色です。
) else (
echo 黄色です。
)
***********************

ご指摘願います。

http://d.hatena.ne.jp/jak-san/20090308/1236501217#c1297301920

ためしてみましたが、call set は動きますが、call if は使えないようですね。
赤色、黄色両方がechoされるのは、call if 〜 ( までが無視されて、ただのecho文
として実行されているのだと思われます(推測)。


個人的にはifの複文は好みでないのですがelseを使いたいのでしょうね。


こんなときは、いったんcall setで別の変数にいれるか、cmd /c を使う方法を
代案として思いつきました。

こんなふうに直してみました。

代案1

REM テキストの内容を取得します。
REM テキスト内容は「リンゴ」、「バナナ」とします。
set i=0
for /f %%i in (%Windir%\test.txt) do @call :add %%i

:add
set x[%i%]=%1
REM 配列の比較     
call set tmp=%%x[%i%]%%
if /%tmp%/==/リンゴ/ ( 
echo 赤色です。
) else (
echo 黄色です。
)
set /a i+=

代案2

REM テキストの内容を取得します。
REM テキスト内容は「リンゴ」、「バナナ」とします。
set i=0
for /f %%i in (%Windir%\test.txt) do @call :add %%i

:add
set x[%i%]=%1
REM 配列の比較     
cmd /C "if /%%x[%i%]%%/==/リンゴ/ ( echo 赤色です。 ) ELSE ( echo 黄色です。)"
set /a i+=

いちどお試しください。