質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

Q&A

解決済

2回答

13962閲覧

コマンドプロンプトでのテキスト内の文字列置換をしたい※windows2003

zazabi

総合スコア24

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

0グッド

0クリップ

投稿2019/08/19 07:52

編集2019/08/26 04:54

<環境>
windows2003

<目的>
大目的:ZabbixAgentインストールのバッチを作成している
小目的(今回の質問):コマンドプロンプトでバッチを作成しており、その中で指定のテキスト内の一部の文字列を変更しなければならない。以下のコマンドで試みているがうまくいかないため、アドバイスが欲しいです。

<コマンド>
@echo off
setlocal
pushd "%~dp0"

rem 設定
set IP=<ZabbixサーバのIPアドレス>
set log_path=zabbix_agentd.log
set hostname=%COMPUTERNAME%

rem ファイル設定
set file=Zabbix Agent
set exe=zabbix_agentd.exe
set conf=zabbix_agentd.conf

rem フォルダ設定
set folder=C:<ファイル名>

rem 以下の「for」ループ内で変数を変化させるための宣言
setlocal enabledelayedexpansion

rem confファイル置換
for /f "delims=" %%a in (<confファイルフルパス>) do (
set line=%%a
set line=!line:(LogFile=c:%log_path%)=(LogFile=c:%folder%%file%%log_path%)!
set line=!line:(Server=127.0.0.1)=(Server=%IP%)!
set line=!line:(ServerActive=127.0.0.1)=(ServerActive=%IP%)!
set line=!line:(Hostname=Windows host)=(Hostname=%hostname%)!

echo !line! >> <confファイルフルパス>
)
popd
pause
<参考にしたサイト>
https://jj-blues.com/cms/wantto-replacestring/

情報が足りないようでしたら追加致しますので指摘してください。
以上、よろしくお願い致します。

#8/23追記
以下のように改善されましたが、まだ未解決です。
仕様としては、batと同じディレクトリにコピーしそこで文字列置換を行った後対象のファイルに上書きする方法にしました。
置換前と置換後のコマンドは問題なく機能しますので、置換するコマンドのみ書かせていただきます。
【コマンド】
@echo off &setlocal
set a=Hostname=Windows host
echo %a%
set b=Hostname=%COMPUTERNAME%
echo %b%
set c=<編集対象ファイルのフルパス>
setlocal enabledelayedexpansion
for /f "usebackq" %%i in ("<置換するためのファイルのフルパス>") do (
set line=%%i
set line=!line:"%a%"="%b%"!
echo !line!>> "%c%"
)
endlocal
pause
【実行前ファイル内容】
a
aaaHostname=Windows hostaaa
a
【実行後ファイル内容】
a
aaaHostname=Windows
a

【試行内容】
set line=!line:"%a%"="%b%"! →だめだった
set line=!line:%a%=%b%! →だめだった
set line=!line:{%a%}={%b%}! →だめだった
set "line=!line:%a%=%b%!" →だめだった

適切に置換できるコマンドを知っている方がいれば、教えてください。
以上、よろしくお願い致します。

#8/26追記
下記のコマンドを実施しましたが、解決しませんでした……。
@echo off
set word1=Hostname=Windows host
set word2=Hostname=%COMPUTERNAME%

set text1=<置換前ファイル>
set text2=<置換後ファイル>

setlocal enabledelayedexpansion
for /f "usebackq" %%i in ("%text1%") do (
echo "%%i" | findstr "%word1%" >NUL && set line=%word2%
echo !line!>> "%text2%"
)

endlocal
pause
【置換前ファイルの内容】
a
a
a
Hostname=Windows host
a
a
a
【置換後ファイルの内容】
ECHO は <OFF> です。
ECHO は <OFF> です。
ECHO は <OFF> です。
Hostname=<ホスト名>
Hostname=<ホスト名>
Hostname=<ホスト名>
Hostname=<ホスト名>

以上、何か思い当たる節があるならば教えていただけたら幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2019/08/19 12:21

> うまくいかないため どうなるんでしょうか?
Zuishin

2019/08/20 05:09

なんでそんな古いサーバーでインストーラー作成してるんですか?
Zuishin

2019/08/23 06:14

なんでそんな古いサーバーでインストーラー作成してるんですか?
guest

回答2

0

ベストアンサー

CMD

1set line=!line:Hostname=Windows host=Hostname=xxxxxxxxxxx!

というコマンドになるので、HostnameWindows host=Hostname=xxxxxxxxxxxに置換することになります。
ということで、: =による置換は無理です。
=^^でエスケープしても無理。

行全体の置換で良いなら、こんな感じで。

CMD

1for /f "usebackq" %%i in ("<置換するためのファイルのフルパス>") do ( 2 set line=%%i 3 echo "%%i" | findstr "%a%" >NUL && set line=%b% 4 echo !line!>> "%c%" 5)

その行にそれ以外の文字があって、そこは変えないという場合は、行の構成をよく見て細かく処理すればなんとかなると思います。

投稿2019/08/23 07:50

編集2019/08/26 05:00
otn

総合スコア84555

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zazabi

2019/08/23 07:56 編集

回答ありがとうございます。 幸い行全体でも問題ない置換なので、やってみようかと思います。 バッチ作成が初めてのため(PowerSellの自動化しかやったことがない)、どのコマンドがどうなるという事が分かっていませんでした…。 最初のコメントも合わせて感謝いたします。
otn

2019/08/23 08:00

本当に行全体が空白も含め完全に一致するなら、 echo "%%i" | findstr "%a%" >NUL && set line=%b% じゃなくて if "%%i" == "%a%" set line=%b% がわかりやすいかと。
otn

2019/08/26 05:01

> 何か思い当たる節があるならば教えていただけたら幸いです。 1行、コピペ漏れがありましたので、訂正しました。 私が間違っておいて言うのもなんですが、これくらいのミスは気付いてほしいです。
zazabi

2019/08/26 05:08 編集

コメント編集ありがとうございます。 指摘されて「そう言えばそうだ」という気持ちでした。わざわざ申し訳ないです…。 「set line=%%i」を追加して、無事置換する事が出来ました。 迅速な反応と分かりやすい指摘ありがとうございます。 ベストアンサーに選ばせていただきます。
guest

0

うまくいかない点が書いてないため問題点の指摘


1.文法上の間違い
set line=!line:(Server=127.0.0.1)=(Server=%IP%)!
だと()がバッチ内でブロックと見做される。(のでたぶんエラーになる)
=を含んだ文字列としたいなら
set line=!line:"Server=127.0.0.1"="Server=%IP%"!
みたいになると思う。

2.for文内で変数を上書きしている
変数lineを何度も上書きしているため、最後に書かれたものしか保存されない(for文とは無関係に、そのブロック内で同じ変数を何度も上書きしているという問題)
一つの変数収めたいなら、改行文字を含めて文字列を連結する工夫が必要。
(LFだけなら^使ってできそうだけど、CRLFだとどうやるのが正解なのかちょっとわかんない)

3.for文で遅延評価された結果で上書きされる
上記2と似て非なるものだけど、変数lineは最終的に評価された値(forで回した最後のループで取得した値)になるので、
set line=%%aの後の処理の実行時に、それまでにfor文で取得していた値は一切参照できていない。

4.ファイルに書く方法が間違ってる
>>でリダイレクトすると「追記」なので、もともと書いてあった内容が消えるわけではない。(ファイル内のエントリが重複する)
ファイルの内容を「書き換え」たいのであれば、何らかの別のコマンドを組み合わせるか、変更のない箇所を含めて全て上書きするような処理が必要。


アドバイスが欲しいです。

正直バッチでやるよりPowerShellなりVBScriptなり使った方が全然楽な気がする、というアドバイスにしておきます。(バッチはファイルを一つのオブジェクトとして扱えないため、すげーめんどくさい)

投稿2019/08/19 22:15

編集2019/08/19 22:23
gentaro

総合スコア8949

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zazabi

2019/08/20 04:41

ご指摘ありがとうございます。 私もPowerSellで行いたいのですが、使用しているサーバに入っていないのでコマンドプロンプトでやるつもりです……。
gentaro

2019/08/20 04:47

あんまりいじれないサーバーでインストールすらできないのであればVBScriptで良いと思いますが。 https://qiita.com/ymk83/items/2191f2beb56e7058901d こういう記事参照すればすぐできそう。 まぁどうしてもバッチで、というなら、頑張ってください。
zazabi

2019/08/20 05:16

ありがとうございます。参考にさせていただきます。
Zuishin

2019/08/20 05:34

なんでそんな古いサーバーでインストーラー作成してるんですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問