プロが教える店舗&オフィスのセキュリティ対策術

いつもお世話になっております。

WindwsXPでDOSバッチを使ってテキストファイル中にある文字列1を文字列2に置換したいのです。
ネットをさまよっていて、こんな例を見つけました。
(参考にしたのはここです。http://www.fpcu.jp/dosvcmd/bbs/log/cat3/cat54/2- …

======================
@echo off
if "%1"=="" goto end
set fname=%1
copy %fname% org >nul
type nul >%fname%
for /f "tokens=1* delims=" %%a in ( org ) do (set line=%%a&& call :sub)

del org
goto end

:sub
:この1行下の acb=xyz に置換前と置換後の文字列を指定する。
set l=%line:abc=xyz%
echo %l%>>%fname%
goto :EOF

:end
======================

これをsample.batという名前で保存し、DOSのウィンドウでsample < a.txt と打つと、a.txtファイル中の"abc"が"xyz"に置き換わります。

これに手を入れて置換前と置換後の文字列を可変にしたく思い、sub中に

set mae=abc
set ato=xyz

の2行を加え、変数に値を設定するようにしました。

ところが、次の1行の書き変え方がわかりません。

set l=%line:abc=xyz%



set l=%line:%abc%=%xyz%%

のように変えてみましたが、うまく動きません。

どなたかご教授いただけませんか。DOSだけでファイル中の文字列の置換ができればset文を使う使わないにはこだわりません。

A 回答 (8件)

No.5 です。



>勝手に引用してしまってすみません。
皆さんに参考にしてもらうために回答しているので気になさらずに引用してください。

さてご質問の件ですが、

◆予備知識
まず、環境変数を%で囲むと、バッチがその行を実行するときに環境変数の中身に置き換えられることを理解してください。
例)
set mae=abc
set ato=xyz

echo %mae% %ato% ←※

※の行が実行されるとき、実際は
echo abc xyz
と置き換えられてecho文が実行されます。

また、バッチ内では %% と%が2つ並んだ記述は1つの%に置き換えられます。

例)echo 10割は100%%
10割は100%


◆今回の場合

call set l=%%line:%mae%=%ato%%%
↓実行されるときに以下のように置き換えられます。
call set l=%line:abc=xyz%

置き換え後に call 文が実行されます。このcall文の記述だと set l=%line:abc=xyz% という1行のバッチを呼び出しているのと同等の動作になります。従って環境変数lineに入っている文字列のabcがxyzに置き換えられた結果が環境変数lに代入されます。
call文でワンクッション置いて、先に環境変数の mae と ato (と%%)だけ評価(環境変数の中身に置き換え)するようにしています。

◆単純に set l=%line:%mae%=%ato%% とした場合なぜうまくいかないか

set文の右辺の各要素を分けて書くと

%line:%(line: という環境変数の中身)→そんな変数は定義していないので空に置き換え

mae

%=%(= という環境変数の中身)→そんな変数は定義できないので空に置き換え

ato

%% → % に置き換え

と解釈されて
環境変数lには maeato% という文字列が代入されてしまいます。


余談ですがバッチ実行時にどのように置き換えられるか見たい場合は、
バッチ先頭のecho offの行を取って実行するとよく分かります。
    • good
    • 0
この回答へのお礼

さっき気づいたのですが、pita-goraさんには前の質問でもお世話になっていたのでした。

http://okwave.jp/qa4253093.html

今回も丁寧な説明、ありがとうございます。たぶんどの本にも載っていないことなのでしょうね。

>このcall文の記述だと set l=%line:abc=xyz% という1行のバッチを呼び出しているのと同等の動作になります。

別バッチにしなくても別バッチのような動きをするのですね。

>◆単純に set l=%line:%mae%=%ato%% とした場合なぜうまくいかないか

むずかしいことをやさしく解説してくださって感激です。

>余談ですがバッチ実行時にどのように置き換えられるか見たい場合は、
>バッチ先頭のecho offの行を取って実行するとよく分かります。

やってみました。

echo offは何も考えずにつけていましたが、これからハマったときははずしてみます。

お礼日時:2008/10/04 10:48

#3です。


何故そうなるかというと、「やってみるとそうなるから」としか言えないです。具体的には#7の方がお書きのような%についての処理が二回起こります。call を重ねれば三回、四回も可能です。

「1行のバッチと同じ」かというと、厳密には違う部分もあるので、別の応用をするなら「%の処理が二回起こる」と考えた方が良いでしょう。#7の方も「このcall文の記述だと」と書いてます。

念のためですが、ヘルプには書いてないので、Undocumentedな仕様ということになります。
Documentedな使用の範囲でやるなら、本当に1行のバッチファイルを作ります。

echo set l=%%line:%mae%=%ato%%% > sub000.bat
cal sub000.bat
del sub000.bat

>「ネットでもsedやawk、WHSを使えって言われましたよ」と言えば、少しは聞いてくれるかもです。

Windows Script Hostは標準装備ですよ。正規表現も使えるし。
    • good
    • 1
この回答へのお礼

notnotさん、いろいろありがとうございます。
>call を重ねれば三回、四回も可能です。
>1行のバッチと同じ」かというと、厳密には違う部分もあるので

大変勉強になります。

>ヘルプには書いてないので、Undocumentedな仕様ということになります。

やはりそうですか。地道に努力していくほかなさそうですね。今回、本当に勉強になりました。


>Windows Script Hostは標準装備ですよ。正規表現も使えるし。

上司が「WSHはOSのバージョンによって動作が異なる。DOSが一番信頼性がある」というスタンスなのです。バージョンによって動作が異なるのはDOSでもありえると思うのですが・・・。

お礼日時:2008/10/04 10:55

/v オプションは CMD.EXEのオプションなので


バッチの起動をする際に
cmd.exe /v:on /C バッチファイル名
といった具合にします
    • good
    • 1
この回答へのお礼

ありがとうございます。教えてちゃんですみません。

お礼日時:2008/10/03 09:29

懐かしいですね。

昔このサンプルを作りました。

ご希望の件ですが

set l=%line:abc=xyz%



call set l=%%line:%mae%=%ato%%%

と書き換えれば希望の動作になると思います。
補足にもかいていますが、このバッチですが、変換するテキストに ">" "<" "|"などバッチのリダイレクションなどに使う記号がある場合や元のファイルに空行(改行のみの行)があるとうまく動かないのでそんな場合は素直にsedやawaやperlを使われた方がいいです。
    • good
    • 1
この回答へのお礼

何とあのサンプルを作られた方ですか。勝手に引用してしまってすみません。http://www.fpcu.jp/dosvcmd/bbs/log/cat3/cat54/2- …での質問者への丁寧な回答に、たいへん好感を持ちました(リダイレクトや空行の補足など)。技術的な知識だけでなく、人間としても素敵な方とお見受けします。

一方私はというと、ANo.3の方へのお礼にも書いたように、なぜcallを付けるのかが理解できていません。「ここを読め」の一言でいいので、何かヒントをいただけないでしょうか。

お礼日時:2008/10/03 09:55

バッチファイルでもできるかも知れないけど、別のツールを使った方が現実的ではなかろうか。

そういう意味で#1さんに賛成。

(sedやawkだと)
>それらをインストールするのに、他の部署の許可&作業依頼を出さないと
>いけないのです。できれば手持ちの道具ですませられればと。

参考にしたというページにも書いてあるけど"Windows Scripting Host"を使うのが現実的だと思いますがね。あくまでもバッチにこだわるのかな...

この回答への補足

回答ありがとうございます。私もWSHで書きたかったのですが、「DOSが一番信頼性がある」という職場なのです。これを機会に、sedやawkをインストールしてくれるよう働きかけてみます。

「ネットでもsedやawk、WHSを使えって言われましたよ」と言えば、少しは聞いてくれるかもです。

補足日時:2008/10/03 09:40
    • good
    • 0

set mae=abc


set ato=xyz
call set l=%%line:%mae%=%ato%%%
    • good
    • 2
この回答へのお礼

魔法のようにできました。でも、なぜできたのかがわかりません。
callというからにはサブルーチン?サブルーチンは書いてないのに?
お願いです。あと一言ヒントをください。

お礼日時:2008/10/03 09:39

バッチの中で環境変数を書き換える場合 起動するCMD.EXEに対して


/v:on のオプションを与えましょう

これを与えないとバッチファイルforコマンドなどでの環境変数の変更が有効になりません
    • good
    • 0
この回答へのお礼

すみません、超初心者なものでおっしゃることがよくわかりません。
オプションを与えるというのは、バッチファイルの中に書くものでしょうか。

お礼日時:2008/10/02 16:55

ふつうは sed とか awk とか perl とかを使うような気がする.


わざわざいばらの道を切り開かんでも....
    • good
    • 1
この回答へのお礼

それらをインストールするのに、他の部署の許可&作業依頼を出さないといけないのです。できれば手持ちの道具ですませられればと。

お礼日時:2008/10/02 16:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A