いつもお世話になっております。
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文を使う使わないにはこだわりません。
No.7ベストアンサー
- 回答日時:
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の行を取って実行するとよく分かります。
さっき気づいたのですが、pita-goraさんには前の質問でもお世話になっていたのでした。
http://okwave.jp/qa4253093.html
今回も丁寧な説明、ありがとうございます。たぶんどの本にも載っていないことなのでしょうね。
>このcall文の記述だと set l=%line:abc=xyz% という1行のバッチを呼び出しているのと同等の動作になります。
別バッチにしなくても別バッチのような動きをするのですね。
>◆単純に set l=%line:%mae%=%ato%% とした場合なぜうまくいかないか
むずかしいことをやさしく解説してくださって感激です。
>余談ですがバッチ実行時にどのように置き換えられるか見たい場合は、
>バッチ先頭のecho offの行を取って実行するとよく分かります。
やってみました。
echo offは何も考えずにつけていましたが、これからハマったときははずしてみます。
No.8
- 回答日時:
#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は標準装備ですよ。正規表現も使えるし。
notnotさん、いろいろありがとうございます。
>call を重ねれば三回、四回も可能です。
>1行のバッチと同じ」かというと、厳密には違う部分もあるので
大変勉強になります。
>ヘルプには書いてないので、Undocumentedな仕様ということになります。
やはりそうですか。地道に努力していくほかなさそうですね。今回、本当に勉強になりました。
>Windows Script Hostは標準装備ですよ。正規表現も使えるし。
上司が「WSHはOSのバージョンによって動作が異なる。DOSが一番信頼性がある」というスタンスなのです。バージョンによって動作が異なるのはDOSでもありえると思うのですが・・・。
No.5
- 回答日時:
懐かしいですね。
昔このサンプルを作りました。ご希望の件ですが
set l=%line:abc=xyz%
を
call set l=%%line:%mae%=%ato%%%
と書き換えれば希望の動作になると思います。
補足にもかいていますが、このバッチですが、変換するテキストに ">" "<" "|"などバッチのリダイレクションなどに使う記号がある場合や元のファイルに空行(改行のみの行)があるとうまく動かないのでそんな場合は素直にsedやawaやperlを使われた方がいいです。
何とあのサンプルを作られた方ですか。勝手に引用してしまってすみません。http://www.fpcu.jp/dosvcmd/bbs/log/cat3/cat54/2- …での質問者への丁寧な回答に、たいへん好感を持ちました(リダイレクトや空行の補足など)。技術的な知識だけでなく、人間としても素敵な方とお見受けします。
一方私はというと、ANo.3の方へのお礼にも書いたように、なぜcallを付けるのかが理解できていません。「ここを読め」の一言でいいので、何かヒントをいただけないでしょうか。
No.4
- 回答日時:
バッチファイルでもできるかも知れないけど、別のツールを使った方が現実的ではなかろうか。
そういう意味で#1さんに賛成。(sedやawkだと)
>それらをインストールするのに、他の部署の許可&作業依頼を出さないと
>いけないのです。できれば手持ちの道具ですませられればと。
参考にしたというページにも書いてあるけど"Windows Scripting Host"を使うのが現実的だと思いますがね。あくまでもバッチにこだわるのかな...
この回答への補足
回答ありがとうございます。私もWSHで書きたかったのですが、「DOSが一番信頼性がある」という職場なのです。これを機会に、sedやawkをインストールしてくれるよう働きかけてみます。
「ネットでもsedやawk、WHSを使えって言われましたよ」と言えば、少しは聞いてくれるかもです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Excel VBAでAA(BBB) → BBB.AA に置換したい 2 2022/10/30 13:59
- Windows 10 Windowsのバッチファイルで正規表現の置換方法について… 4 2022/12/09 16:00
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/15 15:12
- Access(アクセス) アクセス テーブルの空白を変数に置換するボタンが作りたい 4 2022/07/08 11:19
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Visual Basic(VBA) Excel VBA メール作成について 本文の中にExcel でコピーした図を上下に2つ 貼り付けを 2 2023/06/14 01:48
- Visual Basic(VBA) エクセル VBA 条件付き書式 簡略化したい 2 2022/06/02 17:46
- Visual Basic(VBA) 入力ボックスが繰り返しポップアップして止まらない。 下記コードでファイル名の変更をしたいのですが、変 1 2022/09/08 11:27
このQ&Aを見た人はこんなQ&Aも見ています
-
性格の違いは生まれた順番で決まる?長男長女・中間子・末っ子・一人っ子の性格の傾向
同じ環境で生まれ育っても、生まれ順で性格は違うものなのだろうか。家庭教育研究家の田宮由美さんに教えてもらった。
-
Windowsのバッチファイルで正規表現の置換方法について…
Windows 10
-
バッチ処理でファイルの中身を変数に入れるやり方
その他(プログラミング・Web制作)
-
Windowsコマンドラインで文字列置換する方法
工学
-
-
4
Windowsコマンドプロンプトで環境変数の%置換
iOS
-
5
バッチでテキストファイルから任意の行のみ取得したい
その他(プログラミング・Web制作)
-
6
コマンドにてテキストファイルに文字列の追加
UNIX・Linux
-
7
コマンドプロンプトの「%1」と「%~1」の違いがわからない
その他(プログラミング・Web制作)
-
8
バッチファイル内置換
その他(開発・運用・管理)
-
9
バッチファイルの正規表現を利用した文字列検索
その他(プログラミング・Web制作)
-
10
バッチ処理 特定の文字以降をリネーム
Ruby
-
11
echo abc" >> test.txt で、先頭に追加するには?"
その他(OS)
-
12
Dosブロンプトでtabを出力したい
その他(プログラミング・Web制作)
-
13
batファイル処理でのテキストファイルの内容を編集
その他(コンピューター・テクノロジー)
-
14
コマンドプロンプトで相対パスの取得
その他(コンピューター・テクノロジー)
-
15
batである文字列内に特定の文字列が含まれているか確認したい
その他(プログラミング・Web制作)
-
16
バッチファイルで正規表現を使った置換
その他(プログラミング・Web制作)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バッチでテキストファイルから...
-
バッチファイルで昨日の日付を取得
-
コマンドプロンプト標準出力と...
-
コマンドプロンプトで2ヶ月前3...
-
バッチファイルで常に最新の現...
-
コマンドプロンプトでファイル...
-
バッチファイルでDirで取得した...
-
echoとsystem関数について
-
バッチファイル テキストファイ...
-
DOSのバッチで、変数中のファイ...
-
DOSのバッチで、テキストファイ...
-
子バッチ内のキー入力処理へ自...
-
絶対パス名からファイル名を取...
-
rename コマンドでファイル名を...
-
はじめまして。
-
Excelで住所録を地域ごとに振り...
-
VBアプリケーションで終了コー...
-
C#でメジャーなバッチフレーム...
-
コマンドプロンプトの「%1」と...
-
コマンドプロンプトのエラーに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッチでテキストファイルから...
-
コマンドプロンプト標準出力と...
-
コマンドプロンプトで2ヶ月前3...
-
バッチファイルで昨日の日付を取得
-
コマンドプロンプト(バッチファ...
-
絶対パス名からファイル名を取...
-
バッチファイルでDirで取得した...
-
VBアプリケーションで終了コー...
-
DOSのバッチで、テキストファイ...
-
コマンドプロンプト(バッチ)...
-
子バッチ内のキー入力処理へ自...
-
バッチファイルで2つ以上の変...
-
バッチファイルで常に最新の現...
-
コマンドプロンプト画面の閉じ...
-
IPアドレスの第3オクテットだ...
-
コマンドプロンプトでファイル...
-
呼び出し元バッチを知るには?
-
telnetの自動シェルバッチを作...
-
batの変数を直接vbsのプログラ...
-
バッチファイル ファイル内で改...
おすすめ情報