作者: 藤岡和夫
日時: 2008/3/01(09:18)
On Sat, 01 Mar 2008 04:00:44 +0900
davi <davi-1984@...> さんwrote:

> 
> 藤岡和夫さん  <  こん??は でび です
> 
> 月末&&年度末進行の中、ありがとうございます。
> 
> On Sat, 01 Mar 2008 00:59:42 +0900
> 藤岡和夫 <kazuf@...> wrote:
> 
> >  だめか、authorがない場合に出力できないか^^;)
> 
> むーん。藤岡さんでも苦心するとわ。
>
> > > titleの配列は作らずに
> 
> titleはほとんど同じだから、そこを読み飛ばして処理できれば
> 一段階で済みそうですよね。

BEGIN{
    FS=","
}
{ titles[$1] }
$2 == "著者" { author[$1] = $3 }
$2 == "訳者" { trans[$1] = $3 }
$2 == "出版社" { pub[$1] = $3 }
$2 == "出版年" { year[$1] = $3 }
END{
    for (title in titles){
        printf("%s,%s,%s,%s,%s\n",
        title, author[title], trans[title], pub[title],  year[title])
    }
}

 やはり、データの構造として、タイトル以外はすべて揃っているとは限らない
可能性があるので、タイトルを取得する必要があるでしょうね。ということで、
必ずタイトルを取得します。GAWKでは配列を書くだけで定義できるのに気付きま
した。

> このデータ、awkの入門本でよく見かける、空行で区切られた
> 複行レコードにちょっと見したところ似ていますよね。
> 
> そこで、awkで処理してみようか、と思ったのです。
> 
> でも、空行の有無だけでこんなに処理が違ってくるとは思って
> いませんでした。
> 
> あれ?
> もしかして、$1だけ次行と比較していって、違った場合は
> $0の直前に空行を挿入する前処理をすれば、OKだったのでしょうか。

 複行レコードとして取り扱うにはデータの規則性が足りないので、行単位の処
理のほうがよいでしょう。でびさんのスクリプトを生かすとすると、

BEGIN {
    FS = ","
}
{
    title = $1
    if ( prtitle != title && count != 0 ){
        printf( "%s,%s,%s,%s,%s\n", prtitle,author,translator,publisher,year )
        author = "";translator = "";publisher = "";year = ""
    }
    if ( $2 == "著者" ) { author = $3 }
    if ( $2 == "訳者" ) { translator = $3 }
    if ( $2 == "出版社" ) { publisher = $3 }
    if ( $2 == "出版年" ) { year = $3 }
    prtitle = title;count++
}
END{
    printf( "%s,%s,%s,%s,%s\n", prtitle,author,translator,publisher,year )
}

 この方法も常套手段ですが、配列を使って書いた方がわかりやすいでしょう。

藤岡 和夫
kazuf@...
日曜プログラマのひとりごと http://homepage1.nifty.com/kazuf/renewal.html