• ベストアンサー

DOSのバッチで、テキストファイル中の文字を置換したい

いつもお世話になっております。 WindwsXPでDOSバッチを使ってテキストファイル中にある文字列1を文字列2に置換したいのです。 ネットをさまよっていて、こんな例を見つけました。 (参考にしたのはここです。http://www.fpcu.jp/dosvcmd/bbs/log/cat3/cat54/2-0391.html) ====================== @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文を使う使わないにはこだわりません。

質問者が選んだベストアンサー

  • ベストアンサー
  • pita-gora
  • ベストアンサー率70% (102/145)
回答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の行を取って実行するとよく分かります。

meglin888
質問者

お礼

さっき気づいたのですが、pita-goraさんには前の質問でもお世話になっていたのでした。 http://okwave.jp/qa4253093.html 今回も丁寧な説明、ありがとうございます。たぶんどの本にも載っていないことなのでしょうね。 >このcall文の記述だと set l=%line:abc=xyz% という1行のバッチを呼び出しているのと同等の動作になります。 別バッチにしなくても別バッチのような動きをするのですね。 >◆単純に set l=%line:%mae%=%ato%% とした場合なぜうまくいかないか むずかしいことをやさしく解説してくださって感激です。 >余談ですがバッチ実行時にどのように置き換えられるか見たい場合は、 >バッチ先頭のecho offの行を取って実行するとよく分かります。 やってみました。 echo offは何も考えずにつけていましたが、これからハマったときははずしてみます。

その他の回答 (7)

  • notnot
  • ベストアンサー率47% (4846/10257)
回答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は標準装備ですよ。正規表現も使えるし。

meglin888
質問者

お礼

notnotさん、いろいろありがとうございます。 >call を重ねれば三回、四回も可能です。 >1行のバッチと同じ」かというと、厳密には違う部分もあるので 大変勉強になります。 >ヘルプには書いてないので、Undocumentedな仕様ということになります。 やはりそうですか。地道に努力していくほかなさそうですね。今回、本当に勉強になりました。 >Windows Script Hostは標準装備ですよ。正規表現も使えるし。 上司が「WSHはOSのバージョンによって動作が異なる。DOSが一番信頼性がある」というスタンスなのです。バージョンによって動作が異なるのはDOSでもありえると思うのですが・・・。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.6

/v オプションは CMD.EXEのオプションなので バッチの起動をする際に cmd.exe /v:on /C バッチファイル名 といった具合にします

meglin888
質問者

お礼

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

  • pita-gora
  • ベストアンサー率70% (102/145)
回答No.5

懐かしいですね。昔このサンプルを作りました。 ご希望の件ですが set l=%line:abc=xyz% を call set l=%%line:%mae%=%ato%%% と書き換えれば希望の動作になると思います。 補足にもかいていますが、このバッチですが、変換するテキストに ">" "<" "|"などバッチのリダイレクションなどに使う記号がある場合や元のファイルに空行(改行のみの行)があるとうまく動かないのでそんな場合は素直にsedやawaやperlを使われた方がいいです。

meglin888
質問者

お礼

何とあのサンプルを作られた方ですか。勝手に引用してしまってすみません。http://www.fpcu.jp/dosvcmd/bbs/log/cat3/cat54/2-0391.htmlでの質問者への丁寧な回答に、たいへん好感を持ちました(リダイレクトや空行の補足など)。技術的な知識だけでなく、人間としても素敵な方とお見受けします。 一方私はというと、ANo.3の方へのお礼にも書いたように、なぜcallを付けるのかが理解できていません。「ここを読め」の一言でいいので、何かヒントをいただけないでしょうか。

noname#223623
noname#223623
回答No.4

バッチファイルでもできるかも知れないけど、別のツールを使った方が現実的ではなかろうか。そういう意味で#1さんに賛成。 (sedやawkだと) >それらをインストールするのに、他の部署の許可&作業依頼を出さないと >いけないのです。できれば手持ちの道具ですませられればと。 参考にしたというページにも書いてあるけど"Windows Scripting Host"を使うのが現実的だと思いますがね。あくまでもバッチにこだわるのかな...

meglin888
質問者

補足

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

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.3

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

meglin888
質問者

お礼

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

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

バッチの中で環境変数を書き換える場合 起動するCMD.EXEに対して /v:on のオプションを与えましょう これを与えないとバッチファイルforコマンドなどでの環境変数の変更が有効になりません

meglin888
質問者

お礼

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

ふつうは sed とか awk とか perl とかを使うような気がする. わざわざいばらの道を切り開かんでも....

meglin888
質問者

お礼

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

関連するQ&A

  • DOSバッチでUNIXテキストファイルの文字列置換

    お世話になります。 早速ですが、 「DOSバッチでテキストファイルの文字列置換を行うプログラム」がいろいろ紹介されていたので、 皆さんのプログラムを流用させていただき、勝手に継ぎ足したDOSバッチプログラムを以下の ように作りました。 このDOSバッチで置換されたテキストファイルに2つの問題が発生して困っています。 問題 1)UNIXテキストファイルの改行コードがLFからCR+LFに変ってしまう。     文字列置換した後にファイルサイズが大きくなっていたので発見しました。      問題 2)空白行がなくなる。     DOSプログラムでは、対応不可でしょうか?     やはり、sed,awk,WHS,power shell を使わないと解決しませんか? -(DOSプログラム f0.bat)------------------------------------------------------ ::** @echo off setlocal ENABLEDELAYEDEXPANSION set fname=%1 copy /b %fname% org >nul type nul >%fname% for /f "delims=" %%a in (org) do (set line=%%a&&set l=!line:abc=xxx!&&echo !l!>>%fname%) del org goto end :end exit /b 0 -(実行時の標準出力結果 list)----------------------------------------------- C:\>setlocal ENABLEDELAYEDEXPANSION C:\>set fname=t22.txt C:\>copy /b t22.txt org 1>nul C:\>type nul 1>t22.txt C:\>for /F "delims=" %a in (org) do (set line=%a && set l=!line:abc=xxx! && echo !l! 1>>t22.txt ) C:\>(set line=J0000000 && set l=!line:abc=xxx! && echo !l! 1>>t22.txt ) C:\>(set line=HHH && set l=!line:abc=xxx! && echo !l! 1>>t22.txt ) C:\>(set line=519 && set l=!line:abc=xxx! && echo !l! 1>>t22.txt ) C:\>(set line=2011-08-28 12:16:44.98302 && set l=!line:abc=xxx! && echo !l! 1>>t22.txt ) C:\>(set line=2011-08-28 12:16:44.016114 && set l=!line:abc=xxx! && echo !l! 1>>t22.txt ) C:\>(set line=0 && set l=!line:abc=xxx! && echo !l! 1>>t22.txt ) C:\>(set line=abc && set l=!line:abc=xxx! && echo !l! 1>>t22.txt ) C:\>del org C:\>goto end C:\>exit /b 0 --(置換前 t22.org LF改行コード)-------------- J0000000 HHH 519 2011-08-28 12:16:44.98302 2011-08-28 12:16:44.016114 0 abc --(置換後 t22.txt CR+LF改行コード)----------- J0000000 HHH 519 2011-08-28 12:16:44.98302 2011-08-28 12:16:44.016114 0 xxxx ------------------------------------------ 皆さんのご意見、ご指導をお待ちしてます。

  • 以下のtest.batでtest.txt中のダブルコーテションを削除し

    以下のtest.batでtest.txt中のダブルコーテションを削除したいと考えています。 【test.bat】 @echo off if "%1"=="" goto end set fname=%1 copy %fname% org >nul type nul >%fname% for /f %%a in ( org ) do (set line=%%a&& call :sub) del org goto end :sub set l=%line:"=% echo %l%>>%fname% goto :EOF :end 【test.txt】 "test1",101,1 "test2",201,2 "test3",301,3 dos窓からtest.bat test.txtを実行し、test.txt の内容を確認すると、 test1,101, という結果になります。 なぜ、最後の数字が削除されるのか? 2行目、3行目のデータが無くなるのは? というところがわかりません。 単純にダブルコーテーションを削除するにはどうしたらよいでしょうか? よろしくおねがいします。

  • バッチファイル内置換

    バッチファイルで、置換をしたいのですが、"="と"<"の置換が出来ません。 ping出力を「file.txt」へ保存し、保存した「file.txt」を一行づつ読み出し下記を実行しています。 for /f "delims=" %%a in ( orig ) do ( set line=%%a call :sub ) :sub set tmp=%line% set tmp=%tmp:<=,% set tmp=%tmp:= =,,% set tmp=%tmp:"時間" =,% set tmp=%tmp:ms=,ms% echo %tmp%>>%CSV_Name% goto :EOF :end 置換出来ないのは、"=" と "<"の文字だけが置換出来ません。 ネットで調べたのですが、"^" でエスケープしても、""二重引用部でくくっても、正しく置換でき有ません。

  • DOSのバッチファイルについての質問です。

    DOSのバッチファイルについての質問です。 フォルダ内のファイルネームを一括変更したいと考えています。 変更したい文字がたくさんあり、その都度インプットして処理したいと思い 下記のようなバッチを組んだのですが上手く動きません。 何かいい方法があればご教授下さい。よろしくお願いします。 echo off SET /P word= for %%a in (*%word%*) do call :sub "%%a" exit /b :sub set fname=%~1 set fname=%fname:%woad%=ああ% ren %1 "%fname%" goto :EOF

  • Windowsコマンドラインで文字列置換する方法

    Windowsでバッチファイルを作成し、テキストファイルの中の文字列を置換しようとしています。 下記のような内容のバッチファイルを作りました。 ーーーーーーーーー @echo off set fname=.¥change.txt set orgword=bbb set newword=222 copy %fname% orgfile >nul type nul >%fname% for /F %%I in (orgfile) do (set readline=%%I&& call :sub) del org file sub: call set outline=%%readline:%orgword%=%newword%%% echo %outline%>>%fname% go to :eof :end ーーーーーーーーー このバッチを利用して、 change.txt ーーーーーーーーー aaabbbccc ーーーーーーーーー を変換すると、 ーーーーーーーーー aaa222ccc ーーーーーーーーー となってくれますが、 ーーーーーーーーー <aaabbbccc/> ーーーーーーーーー を変換すると、 ーーーーーーーーー ECHO は <OFF> です。 ーーーーーーーーー となってしまいます。 これを、 ーーーーーーーーー <aaa222ccc/> ーーーーーーーーー としたい時にはどのようにしたら良いでしょうか?

  • [Linux] ubuntuでコマンド中の文字列を置換して実行する。

    bashを利用しております。 #mv /abc /abc0 && mv /abc2 /abc 上記コマンドを実行した後、abcという文字列をxyzに置換 (内容的には#mv /xyz /xyz0 && mv /xyz2 /xyzと同一)し、 コマンドを手動で実行する方法を探しています。 ヒストリ置換を用いて 「直前に実行したコマンドのabcという文字列をxyzという文字列に置換して実行する」 にはどのようにすればいいのでしょうか? また、もっといい方法がございましたら、 教えていただけますでしょうか? よろしくお願いいたします。

  • 置換のVBA

    エクセルのあるシート内の「abc」という文字列を「abc20」に置換するには以下で可能ですが、 Sub chikan() Cells.Replace What:="abc", Replacement:="abc" & "20", _ LookAt:=xlPart,SearchOrder:=xlByRows, MatchCase:=False End Sub 「abc」という文字列を連番で「abc20」「abc21」「abc22」・・・・・というふうに置換するにはどうすればいいでしょうか?

  • ファイル名の変更(指定文字を置換)

    powershell(PS)では、カッコ([,])の有るファイル名は利用できません。 そこで、バッチ処理でPSに処理させる下準備でカッコを他の文字(xx)に置換した ファイル名に変名したいと思います。 (PSで処理後に再置換して元のファイル名に戻す予定) 例えば、  [品番001]_Model_s0023.jpeg を  xx品番001xx_Model_s0023.jpeg に変名する。 以前教えてもらったbatを変更して以下のように修正しましたが うまく処理できませんでした。 どのように修正すれば良いでしょうか ? '------------------------------------------------ @echo off rem 該当するファイルを書き換える(カッコ>xx変換) for %%f in ( *.jpeg ) do call :sub "%%f" exit /b :sub set fname=%1 set fname=%fname:[=xx% set fname=%fname:]=xx% ren %1 %fname% goto :EOF

  • バッチファイルでFINDSTRを使って文字列検索をしたいが、ファイルが

    バッチファイルでFINDSTRを使って文字列検索をしたいが、ファイルが開けない (1)と(2)のバッチファイルを作りました。それぞれ単体で実行すると、エラーは出ません。 (1)と(2)を一緒にした(3)というバッチファイルで実行すると、FINDSTRのところで、 「ファイルを開くことができません」というエラーが出て、途中でとまってしまいます。 エラーを出さずに実行する方法は何かないでしょうか? (A.batは、CドライブにあるWord.exeを実行するだけのバッチファイルです。) どうぞよろしくお願いします。 【(3)の中身】 call A.bat >kekka.txt   ←この1行だけが(1)のバッチファイルの中身です GOTO kensaku GOTO :EOF ::文字列検索 :kensaku SET keyword=作成しました。   ←この行から下が(2)のバッチファイルの中身です FINDSTR %keyword% kensaku.txt > NUL GOTO kekka%ERRORLEVEL% GOTO :EOF :kekka0 REM 文字列あり ECHO %keyword%がありました PAUSE > nul GOTO :EOF :kekka1 REM 文字列なし ECHO %keyword%はありませんでした。 PAUSE > nul GOTO :EOF

  • サブフォルダ内含め全てのファイル名を一括置換するw

    サブフォルダ内含め全てのファイル名を一括置換するwindowsバッチ処理について ファイル名の「YYYYMM」部分を一括で変換したく以下の様なバッチ文を記載しました。 しかし置換処理がうまくいかず、ファイル名の後ろに入力文字列がくっついてしまいます。 set /p YYYYMM="年月を入力してください(yyyymm形式):" echo %YYYYMM% for /r %%f in ( * ) do call :sub %%f %YYYYMM% pause exit /b :sub echo %2 set fname=%~nx1 set fname=%%fname:YYYYMM=%2%% echo %fname% ren %1 %fname% goto :EOF 環境上、ファイル名リネームソフトやWindows Powershellを使うことができないため、何とかバッチ処理で楽をしたいのですがかなり煮詰まってしまい。。。 どなたかアドバイスをお願いできないでしょうか。 よろしくお願いいたします。

専門家に質問してみよう