- 締切済み
AWKスクリプト作成法 その3
AWKスクリプトで以下のようなことをやりたいのですが どのようなすればできるでしょうか? いい方法を教えてもらえないでしょうか? 入力ファイル例 LAYER部 LAYER AAPOL 10 LAYER ABPOL 11 LAYER ACON 15 LAYER AM1 17 : 処理部 APOL = AAPOL NOT WIN M1 = AM1 NOT WIN CON = ACON NOT WIN : POL = APOL AND FLD : 修理するファイルの形式 [1] LAYER部 ”LAYER AAPOL 10”といった形式で”AAPOL”が”10”に割り当てられる [2] 処理部 ”APOL = AAPOL NOT WIN”といった形式で各単語が論理演算される。 [2]の処理部では「1]で定義された単語が何度論理演算されているかはわからない。 AWKでおこないたい処理 (1)LAYER部で”10”、”17”で定義された単語(例では”AAPOL”と”AM1”)を取得 (2)処理部で(1)で取得した単語を使用して処理部で作成された全単語を取得
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- terra5
- ベストアンサー率34% (574/1662)
処理部の左辺に表れた単語で右辺に出現していない物のリストが欲しいということだと思いますが。 だとすれば、基本的には既に書いたスクリプトの内容を理解できればもう書けるはずです。 また、エラーチェックしないなら、LAYERに出現しているかどうかは結果には関係ないですね。 処理部の左辺に表れたシンボルをテーブルに単語をキーにして値0として入れ、 右辺に出現したらカウント、 最後にテーブルからカウンタが0の物を選んで出力でできます。 ポイントは for( sym in table )とかif( sym in table )でしょう。
- terra5
- ベストアンサー率34% (574/1662)
>WORD「0」 =”POL” >WORD[1] = ”GAT” >word_number = 1 >といったものを出力として得たいのです。 やっぱりわかりません。 1) なぜ、POSが選択されないのか 2) なぜ、GATより先にPOLが選択されるのか 3) FLDは未定義だがどう扱うのか、 4) なぜ、POLが選択されるのにAPOLが選択されないのか 5) word_number = 1なのは[1]まで使っているという意味か
- terra5
- ベストアンサー率34% (574/1662)
やはり、何をしたいのかよくわかりませんが、 >(1)”LAYER部”で3単語目が例えば”10”の 場合の2単語目(例では”AAPOL”)を取得 LAYER 単語 数値 のパターンの行があった場合、単語をテーブルに格納という意味でよろしいですか。ならば、 if ( $1 == "LAYER " ) def[$2] = $3; で、def[]に格納できます。 ある単語が登録されているかどうかは、 if ( "ABC" in def ) で判定できます。 >(一旦”APOL”となり更にAPOLを使用して>>POLが作成されているのでPOLとなる。 何をしたいのかわかりません。 単に"APOL"をテーブルに入れたいだけなら、 used[$1]++; のような形で登録できますし、有無は if ( .. in .. )の形で、 内容の一覧は for ( s in used ) で、sに"APOL"... と順番に代入されます。
補足
処理の概要は サンプルファイル /* LAYER部 */ LAYER AAPOL 10 LAYER ABPOL 11 LAYER ACON 15 LAYER AM1 17 LAYER WIN 177 /* 処理部 */ APOL = AAPOL NOT WIN BPOL = ABPOL NOT WIN M1 = AM1 NOT WIN GAT = AAPOL AND M1 POL = APOL AND FLD POS = POL NOT BPOL BOOL_END (1) 1単語目が”LAYER” で3単語目が”10”の2単語目を取得 (サンプルでは”AAPOL”) (2)処理部で(1)で取得した単語を使用して論理演算で作成された単語を取得 その際、論理演算で何回か処理されることがあり処理部終端キーワード まで追いかけて単語を取得したい。(作成される単語数は不定) サンプルでは ”APOL = AAPOL NOT WIN”の行でAAPOLからAPOLが作られる 更に”POL = APOL AND M1”の行でAPOLからPOLが作られる。 それと同時に”GAT = AAPOL AND M1”でAAPOLより”GAT”が作られる。 よって出力例としては WORD「0」 =”POL” WORD[1] = ”GAT” word_number = 1 といったものを出力として得たいのです。 実は、この後まだ処理があるのですが、字数の関係でこの部分さえできれば 後は自分でなんとかなりそうなので.. よろしくお願いします。
- terra5
- ベストアンサー率34% (574/1662)
何をしたいかがよくわからないですがこんな感じですか。 連想記憶配列とフィールドセパレータによる単語の分解ができれば、あとはどうにでもなると思います。 よく判らないので、質問が2バイト文字の場合はそのままにしてあります。 def[] ; LAYER部で定義した単語とその値 used[] ; 処理部で出現した単語のその回数 ----------------------------------------- BEGIN { block = 0; FS = "[ \t]" } $1=="LAYER部" { block = 1; } $1=="処理部" { block = 2; $1 = ""; } NF > 2 { if (block==1) layer(); else if (block==2) proc(); } function layer() { for ( i=1 ; i<=NF-2 ; i++ ) { if ( $i == "LAYER" ) { def[$(i+1)] = $(i+2); used[$(i+1)] = 0; } } } function proc() { for ( i=1 ; i<=NF ; i++ ) { if ( $i == "" ) return; if ( $i !~ /(=)|(=)|(NOT)|(AND)/ ) { used[$i]++; } } } END { for( sym in used ) printf("%s(=%s) used %d times\n",sym,def[sym], used[sym]); }
補足
すいません。質問の仕方がよくなかったようです。 まず、最初の質問の”LAYER部”、”処理部”と書いているのは私が後から追加したただのコメントのつもりで書きました。やりたいことは (1)”LAYER部”で3単語目が例えば”10”の 場合の2単語目(例では”AAPOL”)を取得 (2)(1)で取得した単語を利用して処理部で作成されている単語を取得。(例では”APOL = AAPOL NOT WIN”となりAAPOLからAPOLが作成されているので一旦”APOL”となり更にAPOLを使用してPOLが作成されているのでPOLとなる。 (3)(2)のような処理があるキーワードまで続くので それを追いかけていく。 そして、(2)の処理はキーワードまで何回処理されているかはわからないのと、何種類の単語が処理によって作成されているかは判らないので、キーワードまでに作成された単語を何かの配列に格納できればと思うのですが、私がよくわからないのは、ある単語が処理をされて名前がどんどん変わっていくものを追いかけていくある種再起的な処理法がよくわからないのです。(これを再起的とは言わないのかも知れませんが...)
補足
すいません。これは私の単純な記述ミスでした。 このサンプルのケースでは (1) LAYER部でAAPOLが選択される。 (2)処理部で”AAPOL”より論理演算で作成された”APOL”が選択される。 (3)処理部で”AAPOL”より論理演算で作成された”GAT”が選択される。 (4)処理部で”APOL”より論理演算で作成された”POL”が選択される。 (5)処理部で”POL”より論理演算で作成された”POS”が選択される。 よって”AAPOL”より論理演算で作成されたWORDは ”GAT”と”POS”となります。 出力例は WORD[0] = ”POS” WORD[1] = ”GAT” word_number = 1 となります。 ”word_number = 1”の意味は一番最初の”AAPOL”から論理演算で 作成されていったWORDの数が0から1までのつもりで書いています。 WORD配列内の1と2は入れ替わっても問題はないです。 これで理解してもらえればいいのですが.. ”FLD”については サンプルに LAYER AFLD 3 FLD = AFLD NOT WIN の2行を書き忘れていました。