68user's page 掲示板

Prev< No. 4574〜4587> Next  [最新発言に戻る] [過去ログ一覧]
No. 4574 # 68user 2006/04/13 (木) 01:31:52
>>4572 べた
> 他に、良い方法があるのでしたら伺いたいのですが。
まず、syslog の出力には年がないという根本的欠陥があります。なので、
ログファイルを後からチェックするだけでは、完璧な判定はできません。
たとえば
    Apr 9 12:23:00 ... (2005年出力)
    Apr 9 12:23:01 ... (2006年出力)
とか
    Apr 9 12:23:01 ... (2005年出力)
    Apr 9 12:23:00 ... (2006年出力)
というケースもありうるわけです。また、現在 1月1日 0時2分だとして、
1分前に出力されたログ
    Jan 1 00:01:00 ...
と、5分前の時刻
    Dec 31 12:57:00 ...
をソートすると Jan 1 の方が先になり、意図した結果になりません。

それを踏まえた上で、
    - 1年前のログが残っていることはないとみなす
    - 年初 5分は目をつぶる
が許容できるかどうかはあなたが判断してください。なお、Jan や Feb の
ソートについては、sed で 01 や 02 に置換すれば何とでもできるでしょう。

理想は年が記録されるログに乗り換えることですが (=syslog を捨てる)、
それが許されるシチュエーションはあまりないと思いますので、
>>4567 まんたろう
は現実的な落としどころと考えます。


>>4573 ふくし
> Diagnostic-Code: X-Postfix; Host or domain name not found. Name Service
> error for name=W.windows.net type=A: Host not found
Postfix はよく知りませんが、
    http://www.kobitosan.net/postfix/ML/arc.4/msg00048.html
でしょうか。あと、うまくいくかどうかわかりませんが、
    # mail 'dareka@[172.16.10.3]'
と IP アドレスを直接指定するとか。@[..] は IP アドレス指定の場合の
メールアドレス記述方法だったような気がしますが、使ったことはありません。

# http://x68000.q-e-d.net/~68user/rfc/?key=821&target=title

> # nslookup
nslookup は、/etc/hosts を参照しません。

と思ったら、HP-UX の nslookup は参照するんですね。へぇ。
    http://docs.hp.com/ja/B2355-90851/nslookup.1.html

> また、W の Thunderbird から出したメールを
> U の /bin/mail で受けるためには、qpopper のようなプログラムを
> U に入れないといけないのでしょうか。
mail コマンドには POP クライアントの機能はないと思いますので、
W で POP サーバを動かすという前提であれば、
    - W にメールが届くと U に転送し、mail コマンドは /var/spool/mail などを
        直接参照する。
    - U で fetchmail などの POP クライアントを動かし、/var/spool/mail などに
        書き出す。
    - W・U 両方で POP サーバを動かし、W 宛のメールは W の POP サーバから
        取得し、U 宛のメールは U の POP サーバから取得する。
などの方法があります (他にもあると思いますが)。

言うまでもありませんが、要件自体が不適切である可能性もあります。

No. 4575 # ふくし 2006/04/13 (木) 14:35:00
>>4574 さん、ありがとうございます。
  # mail 'dareka@[172.16.10.3]'
を指定すると、

  Diagnostic-Code; X-Postfix; host 172.16.10.3[172.16.10.3] said: 550 5.1.1
  <dareka@[172.16.10.3]>... Not local user, server is not relaid.
  Recipient error (in reply to RCPT TO command)

と言われます。

試みに dareka というコンピューターユーザーを W に作ってみましたが
現象は変わりませんでした ;;;

教えていただいたリンクをたどって
http://www.kobitosan.net/postfix/jhtml/faq.html#intranet
に到達していくつかのことをやってみました。

・/etc/postfix/main.cf で
    disable_dns_lookups = yes と書けば
    /etc/hosts を見に行って W.windows.net の名前解決をしてくれる?
    =>ダメでした(dareka@W.windows.net で host not found になる)

・さらに /etc/postfix/main.cf で
    relayhost = W.windows.net と書く

    =>同じ状況です。
    (# mail dareka@W.windows.net で host not found、
        # mail 'dareka[@172.10.16.3]' で not a local user)

・/etc/postfix/main.cf で
    relayhost = W.windows.net と書く

    =>同じ状況です。
    (# mail dareka@W.windows.net で host not found、
        # mail 'dareka[@172.10.16.3]' で not a local user)
        これ、W.windows.net の smtp サーバーである pmail が
        POP before SMTP auth をやっているのが原因かも・・・。
        (フリー版の制約で切れない)

・relayhost の設定をやめ、
    transport_maps = dbm:/etc/postfix/transport と設定する。
    /etc/postfix/transport の中身を

    windows.net :[W.windows.net]
    .windows.net :[W.windows.net]

    にし、postmap /etc/postfix/transport をしてから、
    postfix reload する。
    (/etc/postfix/transport の前に hash、db、dbm などの何をつけるかは
        postmap が生成するデータベースによる。
        間違うと postfix reload で怒られる)

    =>同じ状況です。

・/etc/postfix/transport の中身を

    windows.net :[172.16.10.3]
    .windows.net :[172.16.10.3]

    とか

    windows.net smtp:[W.windows.net]
    .windows.net smtp:[W.windows.net]

    とか

    windows.net smtp:[172.16.10.3]
    .windows.net smtp:[172.16.10.3]

    とかにしてみる。

    =>同じ状況です。。。

ううーん、困った。
でも人に聞きながらやってると整理がついていいですね (^^)

No. 4577 # べた 2006/04/15 (土) 16:55:45
>>4547
ありがとうございます。
どうも、無理みたいですね。
1年。つまり、同じ年ということであるのならば、何とかできるの
でしょうが、年をまたいでしまうと無理ですね。

>Jan や Feb のソートについては、sed で 01 や 02 に置換すれば
>何とでもできるでしょう。
すみません。方法教えてください。


> >>4567 まんたろう
> は現実的な落としどころと考えます。
現実な落としどころとは。?

No. 4578 # EBA 2006/04/16 (日) 03:01:58
BCCでwindowsプログラムをコンパイルしようとすると
「外部シンボル '_main' が未解決」というのが出てしまいます。
「-WオプションをつけてコンパイルすればWindowsアプリができます」と本に
書いてあるのですが、どうすればいいのかわかりません

No. 4579 # べた 2006/04/18 (火) 23:58:32
以下の様なカンマ区切りのファイルがあります。
001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,,
002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:456,001:002,100:200,A01:A02,0:1
003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:,:,:,A01:A02,:

フィールドの11カラム以降からは、コロン区切りで複数設定されている場合がある
ので、複数行に分けたいのです。

以下の様に、
001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,,
002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,001,100,A01,0
002,a2,a3,a4,a5,a6,a7,a8,a9,a10,222,456,002,200,A02,1
003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,,,A01,
003,a2,a3,a4,a5,a6,a7,a8,a9,a10,222,,,,A02,
に編集し、ファイルに出力したいのですが、11カラム以降の処理が上手く行きません。
3通りほど、試してみたのですが、それぞれ駄目でした。
どこがいけないのかとどうすればよいのかを教えてください。

環境は、
Solaris8、Bシェル
です。

No.1 -----------------------------------------------------------------
#!/bin/sh
#

if [ $# -eq 0 ] ; then
        echo "$0 FileName"
        exit 1
fi

FILE=$1
OUT_FILE=kekka.log
rm ${OUT_FILE} > /dev/null 2>&1

nawk -v OUT=${OUT_FILE} '
function max_desc(lstadr,lst) {
      m=split(lstadr,lst,":") ;
      return m ;
}
{
      cnt=1 ;
      n=split($0,arglst,",") ;
      for(i=11;i<=n;i++) {
              m=max_desc(arglst[i],lst["${i}"]) ;
              if (m>cnt) { cnt=m ; }
      }

      no=1 ;
      for(i=1; i<=cnt; i++) {
            for(j=1; j<=n; j++) {
                  if (j==2) {
                        printf("%d,",no++) >> OUT ;
                  } else if (j==11 || j==12 || j==13 || j==14 || j==15 || j==16) {
                          printf("%s,",lst["${j}"][i]) >> OUT ;
                  } else {
                        printf("%s,",arglst[j]) >> OUT ;
                  }
            }
            printf("\n") >> OUT ;
      }
}' ${FILE}

exit 0

No.2 -----------------------------------------------------------------
#!/bin/sh
#

if [ $# -eq 0 ] ; then
        echo "$0 FileName"
        exit 1
fi

FILE=$1
OUT_FILE=kekka.log
rm ${OUT_FILE} > /dev/null 2>&1

nawk -v OUT=${OUT_FILE} '
function max_desc(lstadr,lst) {
        cnt=split(lstadr,lst,":") ;
        return cnt ;
}
{
        num=1 ;
        n=split($0,arglst,",") ;
        for(i=11;i<=n;i++) {
                ret=max_desc(arglst[i],lst[++x,y]) ;
                if (ret>num) { num=ret ; }
        }
        nf=x ;

        no=1 ;
        for(y=1; y<=num; y++) {
                for(j=1; j<=10; j++) {
                        if (j==2) {
                                printf("%d,",no++) >> OUT ;
                        } else {
                                printf("%s,",arglst[j]) >> OUT ;
                        }
                }
                for(x=1; x<=nf; x++) {
                        printf("%s,",lst[x,y]) >> OUT ;
                }
                printf("\n") >> OUT ;
        }
}' ${FILE}

exit 0

No.3 -----------------------------------------------------------------
#!/bin/sh
#

if [ $# -eq 0 ] ; then
        echo "$0 FileName"
        exit 1
fi

FILE=$1
OUT_FILE=kekka.log
rm ${OUT_FILE} > /dev/null 2>&1

nawk -v OUT=${OUT_FILE} '
function max_desc(lstadr,lst,x) {
        cnt=split(lstadr,arrlst,":") ;

        for(j=1;j<=cnt;j++) {
                lst[x,j]=arrlst[j] ;
        }
        return cnt ;
}
{
        num=1 ;
        n=split($0,arglst,",") ;
        for(i=11;i<=n;i++) {
                ret=max_desc(arglst[i],lst[++x,y],x) ;
                if (ret>num) { num=ret ; }
        }
        nf=x ;

        no=1 ;
        for(y=1; y<=num; y++) {
                for(j=1; j<=10; j++) {
                        if (j==2) {
                                printf("%d,",no++) >> OUT ;
                        } else {
                                printf("%s,",arglst[j]) >> OUT ;
                        }
                }
                for(x=1; x<=nf; x++) {
                        printf("%s,",lst[x,y]) >> OUT ;
                }
                printf("\n") >> OUT ;
        }
}' ${FILE}

exit 0

No. 4580 # zsh 2006/04/19 (水) 13:27:30
>>4579 べた
これが賢いやり方とも思えませんが、一応作ってみました。
------
$ cat a.awk
BEGIN {
        FS=",";
        chk_col=11;
} {
        if ($chk_col ~ /:/) {
                str_head=head_string();
                split_num=split($chk_col, str_foot, ":");
                for (i=1; i<=split_num; i++) {
                        for (j=chk_col+1; j<=NF; j++) {
                                split($j, col_buf, ":");
                                str_foot[i]=sprintf("%s,%s", str_foot[i], col_buf[i]);
                        }
                        print str_head "," str_foot[i];
                }
        } else {
                print;
        }
} function head_string() {
        str_buf=$1;
        for (k=2; k<chk_col; k++) {
                str_buf=sprintf("%s,%s", str_buf, $k);
        }
        return str_buf;
}
------
------
$ cat a
001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,,
002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:456,001:002,100:200,A01:A02,0:1
003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:,:,:,A01:A02,:
------
------
$ awk -f a.awk a
001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,,
002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,001,100,A01,0
002,a2,a3,a4,a5,a6,a7,a8,a9,a10,222,456,002,200,A02,1
003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,,,A01,
003,a2,a3,a4,a5,a6,a7,a8,a9,a10,222,,,,A02,
------

>>4571 68user
今更ですが、Solarisでは

$ echo "Apr 02 12:25:00 ===" | sort -M - logfile | \
    sort -n -k2,3 | cat -n | grep "===" | awk '{print $1}'

等としないとダメみたいです。

No. 4581 # べた 2006/04/19 (水) 16:30:24
>>4580 zsh
zshさん、ありがとうございます。
一応、動いたのですが、フィールド2の値を別の
文字置き換えたいのですが、どうすればよいのですか。

ファイル11以降に「:」で区切られたデータが存在した
場合、データの数分順番に番号を振りたいのです。
なければ、デフォルトで”1”としたいのです。

-----
$ cat a
001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,,
002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:456,001:002,100:200,A01:A02,0:1
003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:,:,:,A01:A02,:

-----
結果
001,1,a3,a4,a5,a6,a7,a8,a9,a10,,,,,,
002,1,a3,a4,a5,a6,a7,a8,a9,a10,111,123,001,100,A01,0
002,2,a3,a4,a5,a6,a7,a8,a9,a10,222,456,002,200,A02,1
003,1,a3,a4,a5,a6,a7,a8,a9,a10,111,123,,,A01,
003,2,a3,a4,a5,a6,a7,a8,a9,a10,222,,,,A02,

No. 4582 # zsh 2006/04/19 (水) 18:42:38
>>4581 べた
適当に直してみました。
------
BEGIN{
        FS=",";
        chk_col=11;
} {
        str_head_1=$1;
        if($chk_col ~ /:/) {
                str_head_2=head_string(chk_col);
                split_num=split($chk_col, str_foot, ":");
                for (i=1; i<=split_num; i++) {
                        for (j=chk_col+1; j<=NF; j++) {
                                split($j, col_buf, ":");
                                str_foot[i]=sprintf("%s,%s", str_foot[i], col_buf[i]);
                        }
                        print str_head_1 "," i "," str_head_2 "," str_foot[i];
                }
        } else {
                str_head_2=head_string(NF);
                print str_head_1 ",1," str_head_2;
        }
} function head_string(chk_point) {
        str_buf=$3;
        for (k=3; k<chk_point; k++) {
                str_buf=sprintf("%s,%s", str_buf, $k);
        }
        return str_buf;
}
------

No. 4583 # べた 2006/04/19 (水) 21:00:53
>>4582 zsh

zshさん、ありがとうございます。
>str_head_2=head_string(NF+1);
>for (k=4; k<chk_point; k++) {
の行を修正したら期待する結果が得られました。

ただ、ファイルのフォーマットに規則性がないことがわかり、
データによっては、正しく出力されないものがでてきました。
フィールド11に、「:」が存在しないデータがあるのです。

a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,SSS,A01,,:
a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,123:456:789:100:100,A01:A02:A03:3A:NTT0001,

「 if($chk_col ~ /:/) {」
の判定を増やし、フィールド番号を取得できればできますか。

No. 4584 # べた 2006/04/19 (水) 22:45:43
>>4582 zsh
>>4583 べた

一応、動きます。
以下のようになるのでしょうか。

BEGIN{
        FS=",";
        chk_col=11;
}
{
        str_head_1=$1;
        split_num=chk_comma_max(NF);
        if(split_num!=0) {
                str_head_2=head_string(chk_col);
                split($chk_col, str_foot, ":");
                for (i=1; i<=split_num; i++) {
                        for (j=chk_col+1; j<=NF; j++) {
                                split($j, col_buf, ":");
                                str_foot[i]=sprintf("%s,%s", str_foot[i], col_buf[i]);
                        }
                        print str_head_1 "," i "," str_head_2 "," str_foot[i];
                }
        } else {
                str_head_2=head_string(NF+1);
                print str_head_1 ",1," str_head_2;
        }
}
function chk_comma_max(chk_point) {
        comma_num=0;
        for (k=chk_col; k<=chk_point; k++) {
                if($k ~ /:/) {
                        comma_num=split($k, s, ":");
                        break;
                }
        }
        return comma_num;
}
function head_string(chk_point) {
        str_buf=$3;
        for (k=4; k<chk_point; k++) {
                str_buf=sprintf("%s,%s", str_buf, $k);
        }
        return str_buf;
}

No. 4585 # まんたろう 2006/04/20 (木) 00:36:53
>>4579 べた

No.1
    m=max_desc(arglst[i],lst["${i}"]) ;
    添え字を利用した配列でいいのかな。
    あまり利用したことはないのでなんとも入れないが、こういうところで
    使えないのではないでしょうか。
    添え字にマッチする文字が出てきたときに、何かするのではなかった
    かと思います。

No.2、No.3
    多次元配列の使い方がおかしいのではないかと思います。
    データをセットする側が多次元配列や、アドレス渡しの戻りができて
    いない。たぶん、縦軸(列)の添え字の値が正しくない。
    縦軸(列)の値ってちゃんととれてますか。

No. 4586 # まんたろう 2006/04/20 (木) 00:44:59
>>4579 べた

多次元配列の使い方が正しいか問題はありますが、書き込みがあった
シェルを使用して、多次元配列で動くのを作ってみました。
一応、動きますが。

-----------------------
#!/bin/sh
#

if [ $# -eq 0 ]; then
        echo "$0 FileName"
        exit 1
fi

FILE=$1
OUT_FILE=kekka.log
rm ${OUT_FILE} > /dev/null 2>&1

nawk -v OUT=${OUT_FILE} '
function max_desc(lstadr,lst,x,y) {
        cnt=split(lstadr,arrlst,":");

        for(y=1;y<=cnt;y++) {
                lst[x,y]=arrlst[y];
        }
        return cnt;
}
{
        num=1;
        row=0;
        col=0;

        n=split($0,arglst,",");
        for(i=11;i<=n;i++) {
                ret=max_desc(arglst[i],lst,++row,col);
                if (ret>num) { num=ret; }
        }

        seqno=1;
        for(y=1; y<=num; y++) {
                for(j=1; j<=10; j++) {
                        if (j==2) {
                                printf("%d,",seqno++) >> OUT ;
                        } else {
                                printf("%s,",arglst[j]) >> OUT;
                        }
                }
                for(x=1; x<=row; x++) {
                        printf("%s",lst[x,y]) >> OUT;
                        if (x!=row) { printf("%s",",") >> OUT; }
                }
                printf("\n") >> OUT;
        }

        for(x=1; x<=row; x++) {
                for(y=1; y<=num; y++) {
                        delete lst[x,y];
                }
        }
}' ${FILE}

exit 0

-----------------------

No. 4587 # S-MSK☆ 2006/04/20 (木) 20:59:08
あるCシェルの本でファイル検査演算子「-f」の意味は
「ファイルは普通のファイル」とあるのですが、
普通の定義が分かりません。
また、逆に普通ではないファイルとはどういったもの
になるのでしょうか??
ご回答頂ければ、幸いです。
宜しくお願い致します。

Prev< No. 4574〜4587> Next  [最新発言に戻る] [過去ログ一覧]