Indexへ
(32193)//【32186】→(32187)
------------------------
【タイトル】AWK外部変形教えてください。
【記事番号】 32186 (*)
【 日時 】08/12/02 19:57
【 発言者 】hi

AWK外部変形教えてください。
 下記の様な外部変形を作っていますが、うまく足し算できませんし、又、プリントも多重書きとなり、うまく実行してくれません。数値はちゃんと取り込んでいるようです。いろいろ試行錯誤しては見ましたが、解決できませんでした。どなたか、ご教授よろしくお願いします。
ちゃんと動くようにしたいし、足し算ができない理由、プリントが多重書きになる理由を知りたいです。
 又、CAD上の文字付数値から数値だけを取り出すスクリプトも教えていただけたらと思います。(例 FH=  123.456  m →123.456)

ファイル名         標高2.BAT
。。。。。。。。。。。。。。。。。。。。。。。。。。
@REM 横断標高
@echo off
echo on
goto 1
REM #jw
REM #cd
REM #h0
REM #0 標高原点(BM)を右クリック
REM #1ch BM標高文字を指示してください。(レイヤ不問)
REM #1 測定点を右クリック
REM #99#
REM #hr
REM #e

:1
jgawk -f 標高2.awk jwc_temp.txt > temp.txt
del jwc_temp.txt
rename temp.txt jwc_temp.txt
pause

。。。。。。。。。。。。。。。。。。。。。。。。
ファイル名      標高2.awk
。。。。。。。。。。。。。。。。。。。。。。。。
BIGIN {}
(/^ch/){getline
        BM=substr($6,2)*1000}

/^hp[0-9]/{x1=$2;y1=$3}
{printf("ch %e %e %e %e \"FH=%1.3f\n",x1,y1,1,0,(y1+BM)/1000)} #標高
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
            終わり


Indexへ
(32186)←【32187】→(32189)
------------------------
【タイトル】Re(1):AWK外部変形教えてください。
【記事番号】 32187 (32186)
【 日時 】08/12/02 23:43
【 発言者 】Kazuo Miyake qqza3hq89@aioros.ocn.ne.jp

▼hiさん:
>AWK外部変形教えてください。
> 下記の様な外部変形を作っていますが、うまく足し算できませんし、又、プリントも多重書きとなり、うまく実行してくれません。数値はちゃんと取り込んでいるようです。いろいろ試行錯誤しては見ましたが、解決できませんでした。どなたか、ご教授よろしくお願いします。
>ちゃんと動くようにしたいし、足し算ができない理由、プリントが多重書きになる理由を知りたいです。
> 又、CAD上の文字付数値から数値だけを取り出すスクリプトも教えていただけたらと思います。(例 FH=  123.456  m →123.456)
>
>ファイル名         標高2.BAT
>。。。。。。。。。。。。。。。。。。。。。。。。。。
>@REM 横断標高
>@echo off
>echo on
>goto 1
>REM #jw
>REM #cd
>REM #h0
>REM #0 標高原点(BM)を右クリック
>REM #1ch BM標高文字を指示してください。(レイヤ不問)
>REM #1 測定点を右クリック
>REM #99#
>REM #hr
>REM #e
>
>:1
>jgawk -f 標高2.awk jwc_temp.txt > temp.txt
>del jwc_temp.txt
>rename temp.txt jwc_temp.txt
>pause
>
>。。。。。。。。。。。。。。。。。。。。。。。。
>ファイル名      標高2.awk
>。。。。。。。。。。。。。。。。。。。。。。。。
>BIGIN {}
>(/^ch/){getline
>        BM=substr($6,2)*1000}
>
>/^hp[0-9]/{x1=$2;y1=$3}
>{printf("ch %e %e %e %e \"FH=%1.3f\n",x1,y1,1,0,(y1+BM)/1000)} #標高
>。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
>            終わり


処理内容が 私の専門外なので とんちんかんな答えかもしれませんが
以下のように修正すれば 動作しましたことを 報告します。

標高2.BAT で

REM #1 測定点を右クリック

REM #2 測定点を右クリック
として

標高2.awk を

/^ch/{ BM=substr($6,2)*1000 }
/^hp[0-9]/{x1=$2;y1=$3
 match($1,/[0-9]+/)
 if( substr($1,RSTART,RLENGTH)+0 != 1 )
 printf("ch %e %e %e %e \"FH=%1.3f\n",x1,y1,1,0,(y1+BM)/1000)} #標高

とすれば 動作すると思います。


なお
(1) #1ch と #1 は 同じ番号なので 避けられたほうがよいと思います。
(2) BIGIN は BEGIN です。

また
(3) (/^ch/){getline
        BM=substr($6,2)*1000}

/^ch/{ BM=substr($6,2)*1000 }
としても差し支えありません。

余談ですが
(4)
 match($1,/[0-9]+/)
 if( substr($1,RSTART,RLENGTH)+0 != 1 )

 gsub(/(ln|ci|ch|-)$/,"",$1)
 if( substr($1,3)+0 != 1 )
とすることもできます。

CAD上の文字付数値から数値だけを取り出すスクリプトは
awk でも結構難しい問題だと個人的には思います。

ただ、例題のように 数値の位置が中央にあれば
 str="FH=  123.456  m"

 split(str,A)
 A[2] #A[1]="FH="; A[2]="123.456"; A[3]="m"
として取り出すこともできます。
このとき str の 空白部分は 半角のスペースだと考えて
います。


Indexへ
(32187)←【32189】→(32191)
------------------------
【タイトル】Re(2):AWK外部変形教えてください。
【記事番号】 32189 (32187)
【 日時 】08/12/03 11:30
【 発言者 】Kazuo Miyake qqza3hq89@aioros.ocn.ne.jp

前回の内容では、足し算ができていませんでした。
下記のように 標高2.awk を訂正すれば足し算は
できます。

BEGIN { CONVFMT = OFMT = "%.15g" }
/^ch/{ BM=substr($6,2)*1000 }
/^hp[0-9]/{
 n++
 match($1,/[0-9]+/)
 x1[ substr($1,RSTART,RLENGTH) ] = $2
 y1[ substr($1,RSTART,RLENGTH) ] = $3}
END {
 for( i=2; i printf("ch %s 1 0 \"FH=%1.3f\n",x1[i] FS y1[i],(y1[i]+BM)/1000)} #標高


Indexへ
(32189)←【32191】→(32200)
------------------------
【タイトル】Re(2):AWK外部変形教えてください。
【記事番号】 32191 (32187)
【 日時 】08/12/03 13:14
【 発言者 】hi

>処理内容が 私の専門外なので とんちんかんな答えかもしれませんが
>以下のように修正すれば 動作しましたことを 報告します。
>
>標高2.BAT で
>
>REM #1 測定点を右クリック
>を
>REM #2 測定点を右クリック
>として
>
>標高2.awk を
>
>/^ch/{ BM=substr($6,2)*1000 }
>/^hp[0-9]/{x1=$2;y1=$3
> match($1,/[0-9]+/)
> if( substr($1,RSTART,RLENGTH)+0 != 1 )
> printf("ch %e %e %e %e \"FH=%1.3f\n",x1,y1,1,0,(y1+BM)/1000)} #標高
>
>とすれば 動作すると思います。
>
>
>なお
>(1) #1ch と #1 は 同じ番号なので 避けられたほうがよいと思います。
>(2) BIGIN は BEGIN です。
>
>また
>(3) (/^ch/){getline
>        BM=substr($6,2)*1000}
>は
> /^ch/{ BM=substr($6,2)*1000 }
>としても差し支えありません。
>
>余談ですが
>(4)
> match($1,/[0-9]+/)
> if( substr($1,RSTART,RLENGTH)+0 != 1 )
>は
> gsub(/(ln|ci|ch|-)$/,"",$1)
> if( substr($1,3)+0 != 1 )
>とすることもできます。
>
>CAD上の文字付数値から数値だけを取り出すスクリプトは
>awk でも結構難しい問題だと個人的には思います。
>
>ただ、例題のように 数値の位置が中央にあれば
> str="FH=  123.456  m"
>を
> split(str,A)
> A[2] #A[1]="FH="; A[2]="123.456"; A[3]="m"
>として取り出すこともできます。
>このとき str の 空白部分は 半角のスペースだと考えて
>います。
Kazuo Miyakeさん、、ご教授ありがとうございます。
おっしゃるとおりの変更を行い、if( substr($1,RSTART,RLENGTH)+0 != 1 )の$1を$3に変えたところ、うまくプリントはしました。→if( substr($3,RSTART,RLENGTH)+0 != 1 )
しかし、最終行のところでBM+y1/1000のBMの値が0または、空となり、y1の値のみが出力されてしまいます。
下記プログラムは、以前投稿のあったもので、BM値を手入力するものですが、これは、ちゃんとBM+$3/1000を足し算してくれます。原因、解決策を知りたいです。
又、match文+if文,gsub文+if文の意味をもう少し詳しく教えていただきたいです。

#標高の書き込みawk
BEGIN {
 for(i=2;i<=ARGC;i++){
    if(ARGV[i]~/^bm/) BM = substr(ARGV[i],3)*1;
      ARGV[i]="";
           }
   }
/^hp[0-9]/{
#   printf("ch %e %e %e %e \"L=%1.3f\n",$2,$3,0,1,$2/1000)  #原点からの水平距離
   printf("ch %e %e %e %e \"FH=%1.3f\n",$2,$3,1,0,BM+$3/1000) #標高
      }


Indexへ
(32191)←【32200】→(32201)
------------------------
【タイトル】Re(3):AWK外部変形教えてください。
【記事番号】 32200 (32191)
【 日時 】08/12/03 21:18
【 発言者 】Kazuo Miyake qqza3hq89@aioros.ocn.ne.jp

▼hiさん:
>>処理内容が 私の専門外なので とんちんかんな答えかもしれませんが
>>以下のように修正すれば 動作しましたことを 報告します。
>>
>>標高2.BAT で
>>
>>REM #1 測定点を右クリック
>>を
>>REM #2 測定点を右クリック
>>として
>>
>>標高2.awk を
>>
>>/^ch/{ BM=substr($6,2)*1000 }
>>/^hp[0-9]/{x1=$2;y1=$3
>> match($1,/[0-9]+/)
>> if( substr($1,RSTART,RLENGTH)+0 != 1 )
>> printf("ch %e %e %e %e \"FH=%1.3f\n",x1,y1,1,0,(y1+BM)/1000)} #標高
>>
>>とすれば 動作すると思います。
>>
>>
>>なお
>>(1) #1ch と #1 は 同じ番号なので 避けられたほうがよいと思います。
>>(2) BIGIN は BEGIN です。
>>
>>また
>>(3) (/^ch/){getline
>>        BM=substr($6,2)*1000}
>>は
>> /^ch/{ BM=substr($6,2)*1000 }
>>としても差し支えありません。
>>
>>余談ですが
>>(4)
>> match($1,/[0-9]+/)
>> if( substr($1,RSTART,RLENGTH)+0 != 1 )
>>は
>> gsub(/(ln|ci|ch|-)$/,"",$1)
>> if( substr($1,3)+0 != 1 )
>>とすることもできます。
>>
>>CAD上の文字付数値から数値だけを取り出すスクリプトは
>>awk でも結構難しい問題だと個人的には思います。
>>
>>ただ、例題のように 数値の位置が中央にあれば
>> str="FH=  123.456  m"
>>を
>> split(str,A)
>> A[2] #A[1]="FH="; A[2]="123.456"; A[3]="m"
>>として取り出すこともできます。
>>このとき str の 空白部分は 半角のスペースだと考えて
>>います。
>Kazuo Miyakeさん、、ご教授ありがとうございます。
>おっしゃるとおりの変更を行い、if( substr($1,RSTART,RLENGTH)+0 != 1 )の$1を$3に変えたところ、うまくプリントはしました。→if( substr($3,RSTART,RLENGTH)+0 != 1 )
>しかし、最終行のところでBM+y1/1000のBMの値が0または、空となり、y1の値のみが出力されてしまいます。
>下記プログラムは、以前投稿のあったもので、BM値を手入力するものですが、これは、ちゃんとBM+$3/1000を足し算してくれます。原因、解決策を知りたいです。
>又、match文+if文,gsub文+if文の意味をもう少し詳しく教えていただきたいです。
>
>#標高の書き込みawk
>BEGIN {
> for(i=2;i<=ARGC;i++){
>    if(ARGV[i]~/^bm/) BM = substr(ARGV[i],3)*1;
>      ARGV[i]="";
>           }
>   }
>/^hp[0-9]/{
>#   printf("ch %e %e %e %e \"L=%1.3f\n",$2,$3,0,1,$2/1000)  #原点からの水平距離
>   printf("ch %e %e %e %e \"FH=%1.3f\n",$2,$3,1,0,BM+$3/1000) #標高
>      }


申し訳けありません。BMが足し算に反映されないままでした。
前回の内容では、足し算ができませんでした。

下記のように 標高2.awk を訂正すれば足し算は
できます。

BEGIN { CONVFMT = OFMT = "%.15g" }
/^ch/{ BM=substr($6,2)*1000 }
/^hp[0-9]/{
 n++
 match($1,/[0-9]+/)
 x1[ substr($1,RSTART,RLENGTH) ] = $2
 y1[ substr($1,RSTART,RLENGTH) ] = $3}
END {
 for( i=2; i<=n; i++ )
 printf("ch %s 1 0 \"FH=%1.3f\n",x1[i] FS y1[i],(y1[i]+BM)/1000)} #標高

反映されない原因は
外部変形の書き出しデータから /^ch/ で BMの値を取得する前に /^hp/ で
指示点の座標値 x1 と y1 の個所が 動作してしまうためでした。
BM値を手入力するものは あらかじめ BMの値が決定しているため問題がないので
すが、今回の件では 私の回答には あきらかに問題がありました。


match文については
mawkに添付されている 日本語訳のコマンドリファレンスを抜粋すれば

mawk MBCS (32bit版) Rel. 27 は
   http://www.vector.co.jp/soft/win95/util/se080308.html
   Vectorのダウンロードサイト から入手できます。

     match(s,r)
           文字列 sの中で正規表現 rにマッチする部分のうち、もっ
           とも左にありかつ最長のものの添え字を火返します。正規
           表現 rにマッチする部分がなければ、関数は0を返します。
           関数の副作用として、RSTARTは関数の戻り値と同じ値が設
           定され、RLENGTHにはマッチしたときにはマッチした部分
           の長さが、マッチしなかったときには-1が設定されます。
           空文字列がマッチした場合には、RLENGTHには0が設定され、
           マッチしたのがはじめの部分であれば1が、最後の部分が
           マッチしたのであればlength(s)+1が戻り値として返され
           る。
      substr(s,i,n) substr(s,i)
           文字列sのi番めの文字からn文字の長さの部分文字列を返
           します。nが省略された場合にはi番めからsの終端までの
           部分文字列が返されます。
      RLENGTH  最後に呼び出したmatch()によってセットされた値が格納
           されています。
      RSTART  最後に呼び出したmatch()によってセットされた値が格納
           されています。

とあります。
ここでの match 文は 多少気取った 書き方です。わかりにくいかもしれません。

また gsub文を利用して
 gsub(/(ln|ci|ch|-)$/,"",$1)
としているのは以下の理由からです。

バッチファイルで文字列を
 REM #1ch
で入力すると 指示点の書き出しデータは
 hp1ch x y
となります。同様に線や円は
 hp1ln x y
 hp1ci x y
となります。

線・円・文字列の指示点の座標も hp1 x y のような形に整形して処理
すれば 指示点の番号が substr($1,3) で取得できるためです。

本件では 文字列の指示点の座標値を取得する必要はないのですが いつも
このように書いているためです。


Indexへ
(32200)←【32201】//(32190)
------------------------
【タイトル】Re(4):AWK外部変形教えてください。
【記事番号】 32201 (32200)
【 日時 】08/12/04 01:24
【 発言者 】hi

Kazuo Miyake1様へ
見事動作しました。感謝感激です。とってもすばらしい技術をお持ちですごくうらやましいです。
原点からの水平距離の書出しとか、文字付数値の、数値の取り出しについては、自己研究してみたいと思います。
又、動作した以上に、細かい解説までしていただいてとてもありがたいですし、私の今後のプログラミングの参考になると思います。解説していただいたものは、私にはheavyなのですが少しじっくり研究してみます。紹介して頂いたmawkに添付されている 日本語訳のコマンドリファレンスも読んでみます。他の外部変形も作成中なのですが、又行き詰ったときには、投稿いたしますのでそのときもよろしく面倒を見ていただけたらと思います。
ありがとうございました。