[前の記事]« フォルダを削除するコマンド
[次の記事]バッチファイルで半年に一度特定のファイルをコピー »

関連オンラインソフト配布サイト:
Vector>ダウンロード(top) |>MS-DOSまたは汎用 | >WindowsVista/XP/2000/NT

▲カテゴリー「FOR /F」索引へ

テキストから、あるパターンの行だけを抜き出すには

1706.
テキストから、あるパターンの行だけを抜き出すには
2007年03月12日(月) 08時09分
sikumi
こんにちは、初めまして!
コマンドプロンプトは高校の頃に、ちょこっと
かじった程度で経験が浅いのですが、VB等の開
発環境が無くても、色々できることに気づきま
した。

今回は勉強目的で、FOR文の勉強をしているところ
なのですが、参考書通りにサンプルを実行させた
いのですが、なかなかうまくいかず。。(-_-;

そこで、知識が豊富な皆さんにご助言を頂きたく
こちらへカキコさせて頂きました。

掲示板のタイトルにも書いていますが
「テキストから、あるパターンの行だけを抜き出す」
手法は、FOR文やIF文等を活用するのが自分の中で
ベストと思いますが、FOR文は、他のコマンドと比
べて敷居が高く、四苦八苦してる状態です(^^;

FOR文について、どのようなプロセスを踏めばいいか
等、参考になるサイトをご存知でしたら、教えて頂
けませんでしょうか。

宜しくお願いします<(__)>


処理したい内容はタイトル通りですが、
ちなみにこんな事をしたいと思っています。

test.txtの一部内容をtext2.txtに出力

AAA ⇒アルファベットの行のみ抜き出す
000 ⇒数値の部分は省略
BBB ⇒上記に同じ
111 ⇒ 〃
CCC ⇒ 〃
222 ⇒ 〃
1707.
Re:テキストから、あるパターンの行だけを抜き出すには
2007年03月12日(月) 11時09分
otn
>「テキストから、あるパターンの行だけを抜き出す」

のであれば標準コマンドの範囲では、FINDSTRを使うのがベストですが、
FOR使用法の学習がしたくて、その題材として上記を選んだと言うことでしょうか?その場合、

・英字を1文字でも含んだ行を抽出
・すべての文字が英字だけの行を抽出

どちががテーマかわかりませんが、どちらにしてもFOR文というより変数展開時の文字列置換(SET /? 参照)がポイントになります。
1708.
Re:テキストから、あるパターンの行だけを抜き出すには
2007年03月12日(月) 12時55分
sikumi
こんにちは。 
早速のレスありがとうございます!


>FINDSTRを使うのがベストですが、
このような関数もあるのですね。とても勉強になります。
後でヘルプやGoogleの検索で参照しようかとおもいます。


>・英字を1文字でも含んだ行を抽出
>・すべての文字が英字だけの行を抽出
前者の方がテーマになります。厳密に言うと頭一文字が
指定された文字の場合っていう条件にしようかと思います。

>FOR使用法の学習がしたくて、その題材として上記を選んだと言うことでしょうか?
そうです!FOR文を使ってもっと複雑な処理を行えるようにするのが最終目標なのですが、
まずは簡単な処理文を作って、徐々にステップアップしていこうと考えています。

>変数展開時の文字列置換(SET /? 参照)がポイントになります。
了解です!参照してみます。


とりあえず、頂いたレスをキーワードにして頑張ってコード組んでみます(^^)ゞ

疑問点や解らない所があった場合、その際は申し訳ない
ですがご助言お願いします<(__;)>

>>「テキストから、あるパターンの行だけを抜き出す」
>
>のであれば標準コマンドの範囲では、FINDSTRを使うのがベストですが、
>FOR使用法の学習がしたくて、その題材として上記を選んだと言うことでしょうか?その場合、
>
>・英字を1文字でも含んだ行を抽出
>・すべての文字が英字だけの行を抽出
>
>どちががテーマかわかりませんが、どちらにしてもFOR文というより変数展開時の文字列置換(SET /? 参照)がポイントになります。


1710.
Re:テキストから、あるパターンの行だけを抜き出すには
2007年03月14日(水) 14時25分
sikumi
otnさん 
一つ課題クリアできました。

コード:
FOR /F "eol=d tokens=1,2,3,4 delims=) " %%i in (test.txt) do @echo %%i)%%j %%k %%l >> test2.txt

テストデータの内容(test.txt)
----------------------------------------------------
data1
(A)111 1111 AA
(B)222 2222 AA
(C)333 3333 AA
(D)444 4444 AA
data2
(E)555 5555 AA
(F)666 6666 AA
(G)777 7777 AA
(H)888 8888 AA
data3
(I)999 9999 AA
(J)000 0000 AA
----------------------------------------------------
 ↓
テスト出力結果の内容(test2.txt)
----------------------------------------------------
(A)111 1111 AA 
(B)222 2222 AA 
(C)333 3333 AA 
(D)444 4444 AA 
(E)555 5555 AA 
(F)666 6666 AA 
(G)777 7777 AA 
(H)888 8888 AA 
(I)999 9999 AA 
(J)000 0000 AA 
----------------------------------------------------

SET関数を使って、処理行おうと思いましたが
計算処理を行うためにはFOR文が視覚的に組みやすそう
だったのでFOR文を使いました。

次のステップに進もうと思いますが、ここで質問があります。

■まずはFOR文の中でのeolの指定についてです。
eol=dと指定した場合、dで始まる行の処理を無視するという設定ができますが、
逆に含まない場合の指定というのは可能でしょうか。

■もう一つが、echoの中での計算の仕方についてです。
上のコードに、計算式を追加させて
@echo %%i)%%j %%k+100 %%l+200 >> test2.txt
という処理をさせたいのですが、中々うまくいきません。
echoの中で計算させたい場合は、どのような記述にすれば
良いかをアドバイスください。

早速のヘルプで申し訳ないですが、宜しくお願いします。

>>「テキストから、あるパターンの行だけを抜き出す」
>
>のであれば標準コマンドの範囲では、FINDSTRを使うのがベストですが、
>FOR使用法の学習がしたくて、その題材として上記を選んだと言うことでしょうか?その場合、
>
>・英字を1文字でも含んだ行を抽出
>・すべての文字が英字だけの行を抽出
>
>どちががテーマかわかりませんが、どちらにしてもFOR文というより変数展開時の文字列置換(SET /? 参照)がポイントになります。


1712.
FORの中でのSETの使い方について質問です
2007年03月16日(金) 16時59分
sikumi
ふうー、お手上げな状態です (笑
計算式を使いたいのですが、どこか記述がおかしいので
しょうか。

test.batの内容***********************************
FOR /F "tokens=1,2,3,4,5* delims=) " %%i in (test.txt) do (
SET I = %%i
SET J = %%j +100
SET K = %%k +150
SET L = %%l
@echo %%I %%J %%K %%L>> test2.txt
)
************************************************

test2.txt(バッチ出力結果)*********************
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
%I %J %K %L
************************************************

もしかしたら、setlocal関数等を使う必要があるのかも
しれませんが記述の仕方が悪くうまく動作しません。
どなたかご教授お願いします<(__;)>

>otnさん 
>一つ課題クリアできました。
>
>コード:
>FOR /F "eol=d tokens=1,2,3,4 delims=) " %%i in (test.txt) do @echo %%i)%%j %%k %%l >> test2.txt
>
>テストデータの内容(test.txt)
>----------------------------------------------------
>data1
>(A)111 1111 AA
>(B)222 2222 AA
>(C)333 3333 AA
>(D)444 4444 AA
>data2
>(E)555 5555 AA
>(F)666 6666 AA
>(G)777 7777 AA
>(H)888 8888 AA
>data3
>(I)999 9999 AA
>(J)000 0000 AA
>----------------------------------------------------
> ↓
>テスト出力結果の内容(test2.txt)
>----------------------------------------------------
>(A)111 1111 AA 
>(B)222 2222 AA 
>(C)333 3333 AA 
>(D)444 4444 AA 
>(E)555 5555 AA 
>(F)666 6666 AA 
>(G)777 7777 AA 
>(H)888 8888 AA 
>(I)999 9999 AA 
>(J)000 0000 AA 
>----------------------------------------------------
>
>SET関数を使って、処理行おうと思いましたが
>計算処理を行うためにはFOR文が視覚的に組みやすそう
>だったのでFOR文を使いました。
>
>次のステップに進もうと思いますが、ここで質問があります。
>
>■まずはFOR文の中でのeolの指定についてです。
>eol=dと指定した場合、dで始まる行の処理を無視するという設定ができますが、
>逆に含まない場合の指定というのは可能でしょうか。
>
>■もう一つが、echoの中での計算の仕方についてです。
>上のコードに、計算式を追加させて
>@echo %%i)%%j %%k+100 %%l+200 >> test2.txt
>という処理をさせたいのですが、中々うまくいきません。
>echoの中で計算させたい場合は、どのような記述にすれば
>良いかをアドバイスください。
>
>早速のヘルプで申し訳ないですが、宜しくお願いします。
>
>>>「テキストから、あるパターンの行だけを抜き出す」
>>
>>のであれば標準コマンドの範囲では、FINDSTRを使うのがベストですが、
>>FOR使用法の学習がしたくて、その題材として上記を選んだと言うことでしょうか?その場合、
>>
>>・英字を1文字でも含んだ行を抽出
>>・すべての文字が英字だけの行を抽出
>>
>>どちががテーマかわかりませんが、どちらにしてもFOR文というより変数展開時の文字列置換(SET /? 参照)がポイントになります。
>
>


1713.
Re:FORの中でのSETの使い方について質問です
2007年03月16日(金) 22時16分
YanaKen◆c0rnJ1Q=
>計算式を使いたいのですが、どこか記述がおかしいので
>しょうか。
>
>test.batの内容***********************************
>FOR /F "tokens=1,2,3,4,5* delims=) " %%i in (test.txt) do (
>SET I = %%i
>SET J = %%j +100
>SET K = %%k +150
>SET L = %%l
>@echo %%I %%J %%K %%L>> test2.txt
>)

 出力結果が「%I %J %K %L」の羅列になっているのは、それらが環境変数であるともforの変数であるとも解釈されていない(バッチファイルのお約束に基づき、単に先頭の%を抜かした文字列がechoされている)からでしょう。

>@echo %%I %%J %%K %%L>> test2.txt
 「%%アルファベット」はforの変数の書式です。ここはSETした「環境変数」を出力したい、という意図かと思いますが、であるならば「%環境変数%」の形式、具体的には%I%、%J%などとすべきかと思われます。
 ただ、そこを直せば期待通り動くかというと、また別の問題があります。
 ( )でくくった中でのバッチ処理は論理的にはすべて「1行」なので、( )内の一連の処理内で参照する環境変数は、ことごとくforの行の処理が始まった時点で実際の値に展開ずみになります。つまり、
 @echo %I% %J% %K% %L%>> test2.txt
 ……のように記述すると、forの処理の直前の時点でのそれぞれの環境変数の値がループの回数分だけ繰り返し出力されてしまいます。

 これを避けるにはcmd.exeが拡張機能として持っている「遅延環境変数の展開」オプションをオンにし、かつ"%"のかわりに"!"を使う必要があります。
 詳細はset /?、cmd /?などで「遅延環境変数」関連を調べてください。(もしくはfor .. do call xxx のかたちで外部サブルーチン化してしまえば、そういった知識なしでも期待通りの動作が得られます)

 いろんな実例はこちらでどうぞ↓
http://fpcu.on.coocan.jp/dosvcmd/bbs/log/cat3/set_path/cat51/

 あと、
>SET J = %%j +100
 ……等の部分は、演算結果を環境変数に入れることを意図されているなら /a スイッチが抜けてる気がします。

YanaKen

1714.
Re:FORの中でのSETの使い方について質問です
2007年03月19日(月) 01時18分
sikumi
Yanakenさん。ありがとうございます。
お陰様で、中々いいところまで辿りつきました。(^^)

test.batの内容*****************************************
FOR /F "tokens=1,2,3,4* delims=) " %%i in (test.txt) do (
SET  I = %%i
SET  /a J = %%j -100
SET  /a K = %%k +150
SET  L = %%l
pause
call call.bat
)

*******************************************************


call.batの内容*****************************************
@echo %I%)%J% %K% %L%>> test2.txt

*******************************************************



test.txtの内容*****************************************
(A)111 1111 AA
(B)222 2222 AA
(C)333 3333 AA
(D)444 4444 AA
(E)555 5555 AA
(F)666 6666 AA
(G)777 7777 AA
(H)888 8888 AA
(I)999 9999 AA
(J)000 0000 AA

*******************************************************

test2.txtの内容(実行結果)*******************************
)211 1261 
)322 2372 
)433 3483 
)544 4594 
)655 5705 
)766 6816 
)877 7927 
)988 9038 
)1099 10149 
*******************************************************

test2.txtの期待値は、
(A)211 1261 AA.......なんですけれども
SET文で作った「I」「L」の変数の部分が見事に抜けてしまってます。

サブルーチンで処理を行った場合、どのような記述にすればよいかを
教えて頂けませんでしょうか。

度々の質問で、申し訳ありません。

>>計算式を使いたいのですが、どこか記述がおかしいので
>>しょうか。
>>
>>test.batの内容***********************************
>>FOR /F "tokens=1,2,3,4,5* delims=) " %%i in (test.txt) do (
>>SET I = %%i
>>SET J = %%j +100
>>SET K = %%k +150
>>SET L = %%l
>>@echo %%I %%J %%K %%L>> test2.txt
>>)
>
> 出力結果が「%I %J %K %L」の羅列になっているのは、それらが環境変数であるともforの変数であるとも解釈されていない(バッチファイルのお約束に基づき、単に先頭の%を抜かした文字列がechoされている)からでしょう。
>
>>@echo %%I %%J %%K %%L>> test2.txt
> 「%%アルファベット」はforの変数の書式です。ここはSETした「環境変数」を出力したい、という意図かと思いますが、であるならば「%環境変数%」の形式、具体的には%I%、%J%などとすべきかと思われます。
> ただ、そこを直せば期待通り動くかというと、また別の問題があります。
> ( )でくくった中でのバッチ処理は論理的にはすべて「1行」なので、( )内の一連の処理内で参照する環境変数は、ことごとくforの行の処理が始まった時点で実際の値に展開ずみになります。つまり、
> @echo %I% %J% %K% %L%>> test2.txt
> ……のように記述すると、forの処理の直前の時点でのそれぞれの環境変数の値がループの回数分だけ繰り返し出力されてしまいます。
>
> これを避けるにはcmd.exeが拡張機能として持っている「遅延環境変数の展開」オプションをオンにし、かつ"%"のかわりに"!"を使う必要があります。
> 詳細はset /?、cmd /?などで「遅延環境変数」関連を調べてください。(もしくはfor .. do call xxx のかたちで外部サブルーチン化してしまえば、そういった知識なしでも期待通りの動作が得られます)
>
> いろんな実例はこちらでどうぞ↓
>http://fpcu.on.coocan.jp/dosvcmd/bbs/log/cat3/set_path/cat51/
>
> あと、
>>SET J = %%j +100
> ……等の部分は、演算結果を環境変数に入れることを意図されているなら /a スイッチが抜けてる気がします。
>
>YanaKen
>


1715.
解決できました^^ ただしかし不安が・・・。
2007年03月19日(月) 05時07分
sikumi
すみません。色々調べていく内に自己解決できました。
やはりプログラムを作るのは楽しいですね。苦労はしますけど
動作するのを見て、作って良かった。と思います(^^)
お陰でつい夜を明かしてしまいましたが(笑)(^^A;

test.batの内容*****************************************
FOR /F "tokens=1,2,3,4* delims=) " %%i in (test.txt) do call call.bat %%i %%j %%k %%l
*******************************************************


call.batの内容*****************************************
SET /a J = %2 + 100
SET /a K = %3 + 200
@echo %1)%J% %K% %4>> test2.txt
*******************************************************



test.txtの内容*****************************************
(A)111 1111 AA
(B)222 2222 AA
(C)333 3333 AA
(D)444 4444 AA
(E)555 5555 AA
(F)666 6666 AA
(G)777 7777 AA
(H)888 8888 AA
(I)999 9999 AA
(J)000 0000 AA
*******************************************************



test2.txtの内容(出力結果)******************************
(A)211 1311 AA
(B)322 2422 AA
(C)433 3533 AA
(D)544 4644 AA
(E)655 5755 AA
(F)766 6866 AA
(G)877 7977 AA
(H)988 9088 AA
(I)1099 10199 AA
(J)100 200 AA
*******************************************************

サブルーチンにコールする際に引数つけて対応させたのですが
記述的に不適切でないような気がしますが・・・如何でしょうか。
初めてFOR文に触れるので自信がありません(苦笑)
自分なら「~する」「こうした方がいい」等 ご指摘があれば
訂正したいと思いますので、宜しくお願いします。<(_ _)>



>Yanakenさん。ありがとうございます。
>お陰様で、中々いいところまで辿りつきました。(^^)
>
>test.batの内容*****************************************
>FOR /F "tokens=1,2,3,4* delims=) " %%i in (test.txt) do (
>SET  I = %%i
>SET  /a J = %%j -100
>SET  /a K = %%k +150
>SET  L = %%l
>pause
>call call.bat
>)
>
>*******************************************************
>
>
>call.batの内容*****************************************
>@echo %I%)%J% %K% %L%>> test2.txt
>
>*******************************************************
>
>
>
>test.txtの内容*****************************************
>(A)111 1111 AA
>(B)222 2222 AA
>(C)333 3333 AA
>(D)444 4444 AA
>(E)555 5555 AA
>(F)666 6666 AA
>(G)777 7777 AA
>(H)888 8888 AA
>(I)999 9999 AA
>(J)000 0000 AA
>
>*******************************************************
>
>test2.txtの内容(実行結果)*******************************
>)211 1261 
>)322 2372 
>)433 3483 
>)544 4594 
>)655 5705 
>)766 6816 
>)877 7927 
>)988 9038 
>)1099 10149 
>*******************************************************
>
>test2.txtの期待値は、
>(A)211 1261 AA.......なんですけれども
>SET文で作った「I」「L」の変数の部分が見事に抜けてしまってます。
>
>サブルーチンで処理を行った場合、どのような記述にすればよいかを
>教えて頂けませんでしょうか。
>
>度々の質問で、申し訳ありません。
1716.
Re:FORの中でのSETの使い方について質問です
2007年03月19日(月) 16時53分
otn
>test.batの内容*****************************************
>FOR /F "tokens=1,2,3,4* delims=) " %%i in (test.txt) do (
>SET  I = %%i
>SET  /a J = %%j -100
>SET  /a K = %%k +150
>SET  L = %%l
>pause
>call call.bat
>)
>
>*******************************************************

空白を下線 _ で示すことにすると、
これだと、「%I_%」という変数に、「_(A」という値をセットしてしまいます。

call.bat で参照しているのは、「%I_%」でなく空白のない「%I%」なので、値は空になります。

set /a でない set 文では変数名の一部や値の一部で空白が意味を持ちます。
別の言い方をすると変数名は英数字だけじゃなくて空白や一部の記号も使えます。また、=の直後や文末の空白も削除されず値の一部としてセットされます。

あと、これは最終版にも言えますが、
>FOR /F "tokens=1,2,3,4* delims=) " %%i 
は、第1トークンを%%iに、第2を%%jに、第3を%%kに、第4を%%lに、第5以降をまとめて%%mにセットするという意味になります。
従って、入力がもし、

(A)100 2000 AA BB

だと BB の部分は出力されないことになります。第4トークン以降に空白や閉じ括弧が絶対に含まれないのなら大丈夫ですが、一般的には、
tokens=1,2,3*
としたほうが安全です。

1717.
Re:FORの中でのSETの使い方について質問です
2007年03月19日(月) 17時00分
otn
>また、=の直後や文末の空白も削除されず値の一部としてセットされます。

ちなみに、↑のおかげで、ウェブページからスクリプトをエディタにコピーペーストすると、行末に余分な空白がくっついて、それがそのまま変数にセットされ、期待通りの動作をしないこともあります。

改行文字の見えるエディタを使うのがいいですね。
1718.
Re:FORの中でのSETの使い方について質問です
2007年03月20日(火) 06時05分
sikumi
otnさん。ご返信ありがとうございます。

>空白を下線 _ で示すことにすると、
>これだと、「%I_%」という変数に、「_(A」という値をセットしてしまいます。
ナルほど!変数がうまくセットできない原因がやっと解りま
した。変数をセットする際は空白には用心します(^^A;

となるとこういう事でしょうか。

test.bat*******************************************
FOR /F "tokens=1,2,3,4* delims=) " %%i in (test.txt) do (
SET I=%%i
SET /a J=%%j+100
SET /a K=%%k+150
SET L=%%l
call call.bat
)
***************************************************

echo.bat*******************************************
@echo %I%)%J% %K% %L%>> test2.txt
***************************************************

test.txt*******************************************
(A)111 1111 AA
(B)222 2222 AA
(C)333 3333 AA
(D)444 4444 AA
(E)555 5555 AA
(F)666 6666 AA
(G)777 7777 AA
(H)888 8888 AA
(I)999 9999 AA
(J)000 0000 AA
***************************************************



>>また、=の直後や文末の空白も削除されず値の一部としてセットされます。
>
>ちなみに、↑のおかげで、ウェブページからスクリプトをエディタにコピーペーストすると、行末に余分な空白がくっついて、それがそのまま変数にセットされ、期待通りの動作をしないこともあります。
>
>改行文字の見えるエディタを使うのがいいですね。
ふむう。これも結構危ない問題ですね。フリーウェアで
適当なものを探してみます。

>だと BB の部分は出力されないことになります。第4トークン以降に空白や閉じ括弧が絶対に含まれないのなら大丈夫ですが、一般的には、
>tokens=1,2,3*
>としたほうが安全です。
delimsで)を区切り線として指定していますので
(A 111 1111 AA
という具合に4つに分割、%%j と%%kに対し計算をできるようにしています。
)を区切り線として、使用してしまったので、のちの
echoで(echo.batの内容)追記しています。
意図しているところが見えにくくて申し訳ないです。

後はこのバッチに分岐処理を付け加えたらノルマ達成です。
もう少し頑張ってみます(^^
訂正です
2007年03月20日(火) 09時13分
sikumi
訂正です。

文章内のecho.bat →call.batに訂正

後で、気づきました(笑


>otnさん。ご返信ありがとうございます。
>
>>空白を下線 _ で示すことにすると、
>>これだと、「%I_%」という変数に、「_(A」という値をセットしてしまいます。
>ナルほど!変数がうまくセットできない原因がやっと解りま
>した。変数をセットする際は空白には用心します(^^A;
>
>となるとこういう事でしょうか。
>
>test.bat*******************************************
>FOR /F "tokens=1,2,3,4* delims=) " %%i in (test.txt) do (
>SET I=%%i
>SET /a J=%%j+100
>SET /a K=%%k+150
>SET L=%%l
>call call.bat
>)
>***************************************************
>
>echo.bat*******************************************
>@echo %I%)%J% %K% %L%>> test2.txt
>***************************************************
>
>test.txt*******************************************
>(A)111 1111 AA
>(B)222 2222 AA
>(C)333 3333 AA
>(D)444 4444 AA
>(E)555 5555 AA
>(F)666 6666 AA
>(G)777 7777 AA
>(H)888 8888 AA
>(I)999 9999 AA
>(J)000 0000 AA
>***************************************************
>
>
>
>>>また、=の直後や文末の空白も削除されず値の一部としてセットされます。
>>
>>ちなみに、↑のおかげで、ウェブページからスクリプトをエディタにコピーペーストすると、行末に余分な空白がくっついて、それがそのまま変数にセットされ、期待通りの動作をしないこともあります。
>>
>>改行文字の見えるエディタを使うのがいいですね。
>ふむう。これも結構危ない問題ですね。フリーウェアで
>適当なものを探してみます。
>
>>だと BB の部分は出力されないことになります。第4トークン以降に空白や閉じ括弧が絶対に含まれないのなら大丈夫ですが、一般的には、
>>tokens=1,2,3*
>>としたほうが安全です。
>delimsで)を区切り線として指定していますので
>(A 111 1111 AA
>という具合に4つに分割、%%j と%%kに対し計算をできるようにしています。
>)を区切り線として、使用してしまったので、のちの
>echoで(echo.batの内容)追記しています。
>意図しているところが見えにくくて申し訳ないです。
>
>後はこのバッチに分岐処理を付け加えたらノルマ達成です。
>もう少し頑張ってみます(^^


1720.
Re:FORの中でのSETの使い方について質問です
2007年03月20日(火) 13時23分
otn
>delimsで)を区切り線として指定していますので
>(A 111 1111 AA
>という具合に4つに分割、%%j と%%kに対し計算をできるようにしています。
>)を区切り線として、使用してしまったので、のちの
>echoで(echo.batの内容)追記しています。
>意図しているところが見えにくくて申し訳ないです。

意図は伝わってますよ。
* の構文が誤解を招きやすいのだと思います。
もう一度私の書いた記述を読み返してください。
1721.
SET関数についての質問です
2007年03月26日(月) 07時06分
sikumi
上記のバッチファイルに分岐処理を付け加えることが
できました。ただ完成までに後少し・・・なんですが(^^;

SET文の中で、文字列を操作するところがありますよね。
その操作の所で行き詰っております。。

具体的には、

SET I=(A)111
SET I=%I:)*=)%

と入力し、Iを"(A)111"⇒"(A)"
という意図で処理させようと思ってるですが、
うまく動作しません。

文字列操作する上で、何か方法があるのでしょうか。


>* の構文が誤解を招きやすいのだと思います。
*の部分なのですが、他のパターンの文字列が来ても
変数に文字をセットできるように意図させています。
1723.
Re:SET関数についての質問です
2007年03月26日(月) 13時21分
otn
>SET I=(A)111
>SET I=%I:)*=)%

括弧による複文中では、閉じ括弧が複文終了の閉じ括弧と見なされます。

SET I=(A^)111
SET I=%I:)*=^)%
もしくは
SET "I=(A)111"
SET "I=%I:)*=)%"
にそれぞれ書き直してください。

>>* の構文が誤解を招きやすいのだと思います。
>*の部分なのですが、他のパターンの文字列が来ても
>変数に文字をセットできるように意図させています。

伝わっているのかなあ。
tokens=1,2,3,4* だと、行が
・第1トークン
・第2トークン
・第3トークン
・第4トークン
・第5トークン以降のすべての文字列
の5つに分解され、5つの変数にそれぞれ格納されますが、お書きのスクリプトは変数を4つしか使っていないので、「第5トークン以降のすべての文字列」が落ちます。
これを、tokens=1,2,3,4,* と書けば誤解を招きにくいと思いますが、これとtokens=1,2,3,4* とは同じ意味です。
1724.
Re:SET関数についての質問です
2007年03月27日(火) 06時07分
じゃく
>>SET I=(A)111
>>SET I=%I:)*=)%
>
その前に、set /?によると

環境変数の置換は、次のように拡張されます:

    %PATH:文字列1=文字列2%

は、PATH 環境変数を展開し、その結果に含まれるすべての "文字列1" を
"文字列2" に置き換えます。"文字列2" に空の文字列を指定すると、展開
された出力からすべての "文字列1" を削除することができます。"文字列1"
をアスタリスクで始め、展開された出力の先頭から、文字列1 の残りの部分
が最初に現れるまでのすべてを一致させることもできます。

ということから文字列1をアスタリスクで始めてないので、
SET I=(A)111
SET I=%I:)*=)%

で意図している(A)111→(A)の置き換えは出来ないと思います。

1725.
Re:SET関数についての質問です
2007年03月27日(火) 09時58分
sikumi
otnさん、じゃくさん。ご返信ありがとうございました。

ふーむ。後もう少しで完成しそうなのに(笑
代用として、もう一回FOR文使ってカッコ閉じ")"の部分
を利用して、分割しようかしら。

ただ、もう少しスマートなやり方があればいいんですけどね。。

皆さんでしたら、どのような形で置き換え処理を行い
ますか?


>>>SET I=(A)111
>>>SET I=%I:)*=)%
>>
>その前に、set /?によると
>
>環境変数の置換は、次のように拡張されます:
>
>    %PATH:文字列1=文字列2%
>
>は、PATH 環境変数を展開し、その結果に含まれるすべての "文字列1" を
>"文字列2" に置き換えます。"文字列2" に空の文字列を指定すると、展開
>された出力からすべての "文字列1" を削除することができます。"文字列1"
>をアスタリスクで始め、展開された出力の先頭から、文字列1 の残りの部分
>が最初に現れるまでのすべてを一致させることもできます。
>
>ということから文字列1をアスタリスクで始めてないので、
>SET I=(A)111
>SET I=%I:)*=)%
>
>で意図している(A)111→(A)の置き換えは出来ないと思います。
>


1726.
Re:SET関数についての質問です
2007年03月27日(火) 12時01分
じゃく
こんにちは。

>ふーむ。後もう少しで完成しそうなのに(笑
>代用として、もう一回FOR文使ってカッコ閉じ")"の部分
>を利用して、分割しようかしら。
>皆さんでしたら、どのような形で置き換え処理を行い
>ますか?
>
>
>>>>SET I=(A)111
>>>>SET I=%I:)*=)%

意見というか疑問なんですが、

>>1719.

に示されているものの改造だとして、 echo.bat を呼び出す前に %I% %J% %K% %L% にそれぞれ
(A 111 .... などと分解してあったのに、なぜまた
>>>>SET I=(A)111
>>>>SET I=%I:)*=)%
このように結合後の文字列を削除しようとしてるのかがよくわかりません。結合する時点で(echo.batを呼ぶ前に)削除しちゃえばいいのではないかと思いますが。
現在完成目前のバッチを提示された方が、いろいろな意見が出ると思います。

1728.
Re:otnさんへ
2007年03月27日(火) 15時32分
sikumi
otnさん。こんにちは。

>>SET I=(A)111
>>SET I=%I:)*=)%
>
>括弧による複文中では、閉じ括弧が複文終了の閉じ括弧と見なされます。
>
>SET I=(A^)111
>SET I=%I:)*=^)%
>もしくは
>SET "I=(A)111"
>SET "I=%I:)*=)%"
>にそれぞれ書き直してください。
>
>>>* の構文が誤解を招きやすいのだと思います。
>>*の部分なのですが、他のパターンの文字列が来ても
>>変数に文字をセットできるように意図させています。
>
>伝わっているのかなあ。
>tokens=1,2,3,4* だと、行が
>・第1トークン
>・第2トークン
>・第3トークン
>・第4トークン
>・第5トークン以降のすべての文字列
>の5つに分解され、5つの変数にそれぞれ格納されますが、お書きのスクリプトは変数を4つしか使っていないので、「第5トークン以降のすべての文字列」が落ちます。
>これを、tokens=1,2,3,4,* と書けば誤解を招きにくいと思いますが、これとtokens=1,2,3,4* とは同じ意味です。

%%lには第4トークンと第5トークン以降のものが
入るものだと、はやとちりしていました。
今は、tokens=1,2,3* から、tokens=1,2,*へ修正しています。
ご指摘ありがとうございました。

※バッチの改修を行いましたので、第5トークンまで
割り当ててたものを、第3トークンまでしか見ないように
省略しています。
1729.
Re:SET関数についての質問です
2007年03月27日(火) 15時35分
sikumi
じゃくさん。こんにちは。


>現在完成目前のバッチを提示された方が、いろいろな意見が出ると思います。
すみません。今作成中のバッチファイル及び、テスト用のファイルのご説明をします。

<各ファイルの説明>
・testA.bat ・・・ 処理用のバッチA
・testB.bat ・・・ 処理用のバッチB
・T001.txt ・・・ バッチ処理前のテキストデータ
・C:\KEKKA\T001.txt ・・・ バッチ処理後のテキストファイル(期待値)

<処理の内容>
T001.txt内の各行のデータでカッコ"("で始まる行のみに、
指定した数値を代入した後にC:\KEKKA\T001.txtへ出力し
それ以外の行(カッコで始まらない行)は、計算をせず
そのままC:\KEKKA\T001.txtへ出力します。

testA.batの内容==========================================================
SET FILENAME=T001
goto %FILENAME%

REM **************座標指定*******************

:T001
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

:T002
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

:T003
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

REM *****************************************

:FORBUN
FOR /F "tokens=1,2,*" %%i in (%FILENAME%.txt) do (
SET I=%%i
SET J=%%j
SET K=%%k
call testB.bat
)
=======================================================================




testB.batの内容========================================================
SET I2=%I:~0,1%
IF %I2% == ( goto ZAHYO
IF not %I2% == ( goto ETC

:ZAHYO
SET I2=%I:*)=%
SET /a I2=%I2%+%TATE%
SET /a J=%J%+%YOKO%
SET I3=%I:)*=%

@echo %I3%%I2% %J% %K%>> C:\KEKKA\%FILENAME%.txt
goto EOF

:ETC
@echo %I%%J%%K%>>  C:\KEKKA\%FILENAME%.txt
=======================================================================


T001.txtの内容(バッチ出力前)===========================================
data1
(A)111 1111 AA
(B)222 2222 AA
(C)333 3333 AA
(D)444 4444 AA
(E)555 5555 AA
data2
(F)666 6666 AA
(G)777 7777 AA
(H)888 8888 AA
(I)999 9999 AA
(J)000 0000 AA
=======================================================================


C:\KEKKA\T001.txtの内容(期待値)========================================
data1
(A)211 1311 AA
(B)322 2422 AA
(C)433 3533 AA
(D)544 4644 AA
(E)655 5755 AA
data2
(F)766 6866 AA
(G)877 7977 AA
(H)988 9088 AA
(I)1099 10199 AA
(J)100 200 AA
=======================================================================
1730.
Re:SET関数についての質問です
2007年03月27日(火) 18時13分
じゃく
こんにちは。


>・testA.bat ・・・ 処理用のバッチA
>・testB.bat ・・・ 処理用のバッチB
>・T001.txt ・・・ バッチ処理前のテキストデータ
>・C:\KEKKA\T001.txt ・・・ バッチ処理後のテキストファイル(期待値)

>:FORBUN
>FOR /F "tokens=1,2,*" %%i in (%FILENAME%.txt) do (

"delims=) "で分解するのをやめちゃったのですね。

当方でとりあえず、期待値が出力されるバッチ testA.bat を作ってみました。
testB.bat は testA.bat 内のサブルーチンとして統合してます。

------------------------------------------------ testA.bat
SET FILENAME=T001
goto %FILENAME%

REM **************座標指定*******************

:T001
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

:T002
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

:T003
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

REM *****************************************

:FORBUN
FOR /F "tokens=1,2,3* delims=) " %%i in (%FILENAME%.txt) do call :sub %%i %%j %%k %%l
exit /b

:sub
set x=%1
if not /%x:~0,1%==/( goto ETC
set /a t = TATE + %2
set /a y = YOKO + %3
echo %1)%t% %y% %4>>  C:\KEKKA\%FILENAME%.txt
goto :EOF
:ETC
echo %*>> C:\KEKKA\%FILENAME%.txt
goto :EOF



1733.
Re:ECHOに変数を渡す際の不具合
2007年03月28日(水) 17時05分
sikumi
じゃくさん、ご返信ありがとうございます(^^)
知識不足な私にとって、引数の渡し方など、参考になります。
とてもスマートなフローで美しい。
今作っているものをとりあえずプログラムとして動くようになりましたら、
第2版を作る際に、じゃくさんのコードをご参考させて頂こうかと思います。

ようやく、最終の詰めの所まで来ることができました。
これで最後の質問にしたいと思っていますが、変数の内容をECHOで
返した場合、文字がうまく反映されない事があります。
最初に%が来て、その次に空白スペース入るような行に来ると
その次以降の同じパターンの行自体が無かったかのように
無視して処理されてしまいます。


<問題の起きているテストバッチの一部>
@echo %I%>> C:\KEKKA\T003.txt
※変数Iには、T002.txtの各行のデータが順次入ってきます。

<T002.txt (最終デバッグ用のテストデータ)>
%data 1 1
(A)111 1111 AA
(B)222 2222 AA
(C)333 3333 AA
(D)444 4444 AA
(E)555 5555 AA
%data 2 2
(F)666 6666 AA
(G)777 7777 AA
(H)888 8888 AA
(I)999 9999 AA
(J)000 0000 AA

<T002.txt(実行後の処理)>
%data 1 
(A)211 911 AA
(B)322 2022 AA
(C)433 3133 AA
(D)544 4244 AA
(E)655 5355 AA
(F)766 6466 AA
(G)877 7577 AA
(H)988 8688 AA
(I)1099 9799 AA
(J)100 -200 AA

<T002.txt(期待値)>
%data 1 1
(A)211 911 AA
(B)322 2022 AA
(C)433 3133 AA
(D)544 4244 AA
(E)655 5355 AA
%data 2 2
(F)766 6466 AA
(G)877 7577 AA
(H)988 8688 AA
(I)1099 9799 AA
(J)100 -200 AA

最後のデバッグを行う際に、この問題に突き当たりました。
"("から始まる行以外の文字は、計算等は一切せず、そのまま
出力結果のテキストに反映させたいのですが、どのようなECHO
の記述をすればいいか教えて頂けませんでしょうか。
また"("から始まる行以外の文字列は、不特定な文字列が入ることを
シュミレートしています。

すいませんが、宜しくお願いします。


>こんにちは。
>
>
>>・testA.bat ・・・ 処理用のバッチA
>>・testB.bat ・・・ 処理用のバッチB
>>・T001.txt ・・・ バッチ処理前のテキストデータ
>>・C:\KEKKA\T001.txt ・・・ バッチ処理後のテキストファイル(期待値)
>
>>:FORBUN
>>FOR /F "tokens=1,2,*" %%i in (%FILENAME%.txt) do (
>
>"delims=) "で分解するのをやめちゃったのですね。
>
>当方でとりあえず、期待値が出力されるバッチ testA.bat を作ってみました。
>testB.bat は testA.bat 内のサブルーチンとして統合してます。
>
>------------------------------------------------ testA.bat
>SET FILENAME=T001
>goto %FILENAME%
>
>REM **************座標指定*******************
>
>:T001
>SET /a TATE = 100
>SET /a YOKO = 200
>goto FORBUN
>
>:T002
>SET /a TATE = 100
>SET /a YOKO = 200
>goto FORBUN
>
>:T003
>SET /a TATE = 100
>SET /a YOKO = 200
>goto FORBUN
>
>REM *****************************************
>
>:FORBUN
>FOR /F "tokens=1,2,3* delims=) " %%i in (%FILENAME%.txt) do call :sub %%i %%j %%k %%l
>exit /b
>
>:sub
>set x=%1
>if not /%x:~0,1%==/( goto ETC
>set /a t = TATE + %2
>set /a y = YOKO + %3
>echo %1)%t% %y% %4>>  C:\KEKKA\%FILENAME%.txt
>goto :EOF
>:ETC
>echo %*>> C:\KEKKA\%FILENAME%.txt
>goto :EOF
>
>
>


1734.
Re:ECHOに変数を渡す際の不具合(追記)
2007年03月28日(水) 17時35分
sikumi
現在作成中のバッチです。体裁については、目を瞑って
おいてください(笑)

==============testA.batの内容===========================================
SET FILENAME=T002
del C:\KEKKA\%FILENAME%.txt
goto %FILENAME%

REM ********************************************************************
REM 座標の修正用変数の設定
REM ********************************************************************
:T001
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

:T002
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

:T003
SET /a TATE = 100
SET /a YOKO = 200
goto FORBUN

:XXXX
move %FILENAME%.txt C:\KEKKA\%FILENAME%.txt
goto EOF



REM ********************************************************************
REM テストデータから各行のデータを変数Iに代入する
REM ********************************************************************
:FORBUN
FOR /F "tokens=*" %%i in (%FILENAME%.txt) do (
SET I=%%i
call testB.bat
)
del temp.txt




==============testB.batの内容===========================================
rem *************************************************
rem testAのFOR文で出力した第1トークンの内容をIF文で
rem 分岐処理を行い、処理結果を出力する。
rem *************************************************
SET I1=%I:~0,1%
IF %I1% == ( goto ZAHYO
IF not %I1% == ( goto ETC


:ZAHYO
@echo %I%>temp.txt
call testC.bat
SET /a I3=%I3%+%TATE%
SET /a I4=%I4%-%YOKO%
@echo %I2%)%I3% %I4% %I5%>> C:\KEKKA\%FILENAME%.txt
goto :EOF


:ETC
@echo %I%>> C:\KEKKA\%FILENAME%.txt




==============testC.batの内容=============================================
rem *************************************************
rem testAのFOR文で出力した第1トークンの内容を分割
rem *************************************************
FOR /F "tokens=1,2,3,* delims=) " %%i in (temp.txt) do (
SET I2=%%i
SET I3=%%j
SET I4=%%k
SET I5=%%l
)




==============T002.txtの内容===============================================
%data 1 1
(A)111 1111 AA
(B)222 2222 AA
(C)333 3333 AA
(D)444 4444 AA
(E)555 5555 AA
%data 2 2
(F)666 6666 AA
(G)777 7777 AA
(H)888 8888 AA
(I)999 9999 AA
(J)000 0000 AA
1735.
Re:ECHOに変数を渡す際の不具合(追記)
2007年03月28日(水) 18時29分
otn
>@echo %I2%)%I3% %I4% %I5%>> C:\KEKKA\%FILENAME%.txt

>@echo %I%>> C:\KEKKA\%FILENAME%.txt

ファイルディスクリプタ(ファイル記述子)というものがありまして、標準入力が 0 、標準出力が   1 、エラー出力が 2 という風に一桁の数字です。リダイレクト記号の前にこの数字を指定することができます。

echo AAA >OUT.TXT

echo AAA 1>OUT.TXT
はおなじ。
echo AAA 2>OUT.TXT
は、echoのエラー出力のリダイレクトですが、echoはエラー出力をしないので、OUT.TXTは空になり、画面にAAAが表示されます。

このあたり、unixのシェルの入門書とかを読むといいのですが。

結論から言うと、
echo %AAA%>>OUT.TXT
などと書くと、変数AAAの値の末尾が数字でその直前が空白の場合、上記の状況になるので、おそらく意図しない動作になります。
AAAの値がそのような可能性がある場合、
>>OUT.TXT echo %AAA%
のようにリダイレクトを先に書きます。

 


 

1706.テキストから、あるパターンの行だけを抜き出すには sikumi 07/03/12(月) 08:09
1707.Re:テキストから、あるパターンの行だけを抜き出すには otn 07/03/12(月) 11:09
1708.Re:テキストから、あるパターンの行だけを抜き出すには sikumi 07/03/12(月) 12:55
1710.Re:テキストから、あるパターンの行だけを抜き出すには sikumi 07/03/14(水) 14:25
1712.FORの中でのSETの使い方について質問です sikumi 07/03/16(金) 16:59
1713.Re:FORの中でのSETの使い方について質問です YanaKen◆c0rnJ1Q= 07/03/16(金) 22:16
1714.Re:FORの中でのSETの使い方について質問です sikumi 07/03/19(月) 01:18
1715.解決できました^^ ただしかし不安が・・・。 sikumi 07/03/19(月) 05:07
1716.Re:FORの中でのSETの使い方について質問です otn 07/03/19(月) 16:53
1717.Re:FORの中でのSETの使い方について質問です otn 07/03/19(月) 17:00
1718.Re:FORの中でのSETの使い方について質問です sikumi 07/03/20(火) 06:05
1719.訂正です sikumi 07/03/20(火) 09:13
1720.Re:FORの中でのSETの使い方について質問です otn 07/03/20(火) 13:23
1721.SET関数についての質問です sikumi 07/03/26(月) 07:06
1723.Re:SET関数についての質問です otn 07/03/26(月) 13:21
1724.Re:SET関数についての質問です じゃく 07/03/27(火) 06:07
1725.Re:SET関数についての質問です sikumi 07/03/27(火) 09:58
1726.Re:SET関数についての質問です じゃく 07/03/27(火) 12:01
1729.Re:SET関数についての質問です sikumi 07/03/27(火) 15:35
1730.Re:SET関数についての質問です じゃく 07/03/27(火) 18:13
1733.Re:ECHOに変数を渡す際の不具合 sikumi 07/03/28(水) 17:05
1734.Re:ECHOに変数を渡す際の不具合(追記) sikumi 07/03/28(水) 17:35
1735.Re:ECHOに変数を渡す際の不具合(追記) otn 07/03/28(水) 18:29
1728.Re:otnさんへ sikumi 07/03/27(火) 15:32
 
 


カテゴリー「FOR /F」索引へ

 

カテゴリー一覧

FPCU/FPCDIY QUICK LINK online
この上の各ジャンル名をクリックすると、下のウィンドウが切り替わります▼


=リンク集のインデックスはこちら=

資料書籍

About

2007年03月12日 15:08に投稿されたエントリーのページです。

ひとつ前の投稿は「フォルダを削除するコマンド」です。

次の投稿は「バッチファイルで半年に一度特定のファイルをコピー」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

This site is powered by Six Apart
Movable Type 3.33-ja
 
このブログについて | 運営:有限会社メディアポート