68user's page 掲示板

Prev< No. 4566〜4648> Next  [最新発言に戻る] [過去ログ一覧]
No. 4566 # べた 2006/04/08 (土) 12:36:36
あるファイルから指定日時以降に書かれたレコードを
抽出したいのですが、シェルスクリプトでできるので
しょうか。
どのしょうにシェルにすればよいか教えてください。

例えば、今が、2006/04/08 12:30:00とします。
ある指定日時というのは、現時点から5分前としますので、
2006/04/08 12:25:00となります。

ファイルでは、「Apr 8 12:30:33 ・・・・・」と出力
されているので、5分まえの時間を、「Apr 8 12:25:00」
で取得し、「Apr 8 12:25:00」以降に書かれたレコードを
ファイルに出力したいのです。

環境は、
Solaris8、sh、Perlで実現したいのです。

No. 4567 # まんたろう 2006/04/10 (月) 21:07:44
>>4566 べた

無理ではないかと思うのですが。
「Apr 8 12:30:33 ・・・・・」の比較、チェックが簡単
にできないと思います。

こういうのはどうですか。
5分前に動いた時のファイルのレコード数と今回動いた時の
ファイルにレコード数の差をtailコマンドでファイルに出力
というのは。?

No. 4568 # 68user 2006/04/11 (火) 10:22:32
>>4567 まんたろう
> 「Apr 8 12:30:33 ・・・・・」の比較、チェックが簡単にできないと思います。
echo "Apr 02 12:25:00 ===" | sort -M - logfile | cat -n | grep "===" | awk '{print $1}'
として行番号をとって、その行以降を tail で出力とか。

まぁ筋の悪いやり方だとは思いますので、他の方法がよいでしょう。

No. 4569 # べた 2006/04/11 (火) 12:50:22
>>4568 68user

>echo "Apr 02 12:25:00 ===" | sort -M - logfile | cat -n | grep "===" | awk '{print $1}'
>として行番号をとって、その行以降を tail で出力とか。
予めファイルの全体のレコード数も必要ということですか。
マイナスとなった場合、どうなるのですか。?

No. 4570 # べた 2006/04/11 (火) 14:56:25
>>4578 EBA

echo "Apr 10 09:30:00 ===" | sort -M - logfile | cat -n | grep "===" | awk '{print $1}'
と実行してみたのですが、行番号が2となります。

# cat logfile
<pre>
Apr 9 12:23:01 ・・・・・・・
Apr 9 15:17:43 ・・・・・・・
Apr 9 17:48:06 ・・・・・・・
Apr 9 18:05:30 ・・・・・・・
Apr 9 18:06:24 ・・・・・・・
Apr 10 09:23:08 ・・・・・・・
Apr 10 11:47:23 ・・・・・・・
Apr 10 13:35:49 ・・・・・・・
Apr 11 09:54:11 ・・・・・・・
Apr 11 12:17:38 ・・・・・・・
</pre>

行番号ではなく、すべてを表示したのですが、
sortが正しく行われていないみたいなのですが、
どうしてなのでしょうか。
<pre>
# echo "Apr 10 09:30:00 ===" | sort -M - logfile | cat -n
          1 Apr 9 12:23:01 ・・・・・・・
          2 Apr 10 09:30:00 ===
          3 Apr 9 15:17:43 ・・・・・・・
          4 Apr 9 17:48:06 ・・・・・・・
          5 Apr 9 18:05:30 ・・・・・・・
          6 Apr 9 18:06:24 ・・・・・・・
          7 Apr 10 09:23:08 ・・・・・・・
          8 Apr 10 11:47:23 ・・・・・・・
          9 Apr 10 13:35:49 ・・・・・・・
        10 Apr 11 09:54:11 ・・・・・・・
        11 Apr 11 12:17:38 ・・・・・・・
</pre>

行番号以降をtailで出力は、
# tail +行番号 logfile
でできました。

赤色の文字は 「Windows 機種依存文字」か、いわゆる「半角カナ」です。 この掲示板では自動変換されますが、今後は使用しないで下さい

No. 4571 # 68user 2006/04/12 (水) 11:30:06
>>4570 べた
Linux ではうまくいきましたが、Solaris 環境がないので確認できません。
どなたかご確認いただけませんか?

あと、このやり方は新年 00:00:00〜00:05:00 の間はうまく動作しませんので、
おすすめしません。念のため。

No. 4572 # べた 2006/04/12 (水) 17:05:17
>>4571 68user
ありがとうございます。

>あと、このやり方は新年 00:00:00〜00:05:00 の間はうまく動作しませんので、
>おすすめしません。念のため。
確認して頂いたのですか。
良い方法だと思ってはいたのですが、ダメですか。
他に、良い方法があるのでしたら伺いたいのですが。

No. 4573 # ふくし 2006/04/12 (水) 21:16:07
おひさしぶりです。自分が困ったときだけ出てきてすみません。

Windows のマシンと UNIX のマシンが存在する LAN で、
お互いにメールを送りあうというテストをやっています。
ここでは簡単のため、Windows マシン1台と UNIX マシン1台とします。

W に pmail というフリーウェアの SMTP / POP サーバーを入れた人がいて、
W と U の両方に Mozilla Thunderbird を入れて、
Thunderbird のアカウント設定で、
W の IP アドレスを SMTP / POP アドレス欄に指定することで、
W と U の間でメールのやり取りをすることができました。

しかし、テストの要件のひとつに、
U 側では MUA として /bin/mail も使えるようにする、というものがありました。
sendmail の設定を変えようとしようと思ったのですが、
それは大変だからやめたほうがいいと上司に言われ、
言われるままに U に Postfix を入れました。
ちなみに U の OS は HP-UX 11i ver.2 です。

Postfix のインストールはなんとなく終わりました。
/etc/postfix/main.cf に
myhostaname = U.unix.net
と変更を加えました。

DNS を立てるのはなかなか面倒だと上司に言われたので、言われるままに
U の /etc/hosts および
W の C:\Winnt\system32\drivers\etc\hosts に
172.16.10.2 U.unix.net
172.16.10.3 W.windows.net
のように書きました。

で、U 側で
  # mail root
  nantoka
  kantoka
  .
のように書くと、
  # mail
で自分宛に出したメールが確認できましたが、
  # mail dareka@W.windows.net
  nandakakandaka
  .
のようにすると、
  Diagnostic-Code: X-Postfix; Host or domain name not found. Name Service
    error for name=W.windows.net type=A: Host not found
のように怒られます。

(ここで、dareka は W の pmail に設定したメールアカウントです。)

U から
  # nslookup
  > W.windows.net

とすると 172.16.10.3 が、

  > 172.16.10.3

とすると W.windows.net が正しく帰るのですが、
host W.windows.net とすると not found 3(NXDOMAIN) と言われます。
このへんが原因でしょうか。

この状況で、U から W に /bin/mail でメールを出すことができるでしょうか。

また、W の Thunderbird から出したメールを
U の /bin/mail で受けるためには、qpopper のようなプログラムを
U に入れないといけないのでしょうか。

他に、いまの私の状況でもっと簡単にテストするアイディアがわかれば
ご教示ください。

いろいろ聞いてすみません。よろしくお願いします。

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」の意味は
「ファイルは普通のファイル」とあるのですが、
普通の定義が分かりません。
また、逆に普通ではないファイルとはどういったもの
になるのでしょうか??
ご回答頂ければ、幸いです。
宜しくお願い致します。

No. 4588 # 68user 2006/04/21 (金) 11:02:50
>>4575 ふくし
もう解決されているとは思いますが一応。

Postfix に hosts を参照させるのが一番の早道かつ王道だと思いますが
わたしは Postfix を知らないので、識者のいるメーリングリストなどで
質問するのがよいかと思います。

>>4587 S-MSK☆
> 「ファイルは普通のファイル」とあるのですが、
> 普通の定義が分かりません。
csh 的には、stat(2) した結果の st_mode (構造体 stat のメンバ) に対して、
通常ファイル判定マクロ S_ISREG が真を返したら、「普通」です。

では S_ISREG がどういうケースで真を返すかというと、vfs の vtype の
値が VREG であるときです (vtype はファイル作成時に決定され、ファイル
システムに記録される)。

では vfs の vtype の値が VREG であるのはどういうときかというと、
ファイルシステム依存です。ただし一般的な UFS で言うと、vtype は
    1. シンボリックリンク
    2. ソケット
    3. FIFO (名前付きパイプ)
    4. デバイスファイル (キャラクタデバイス・ブロックデバイス)

    5. 通常ファイル
くらいです。よって、大抵の場合 1〜4 に当てはまらないなら通常ファイル
といえます。

実際は、Solaris Door とか、VxFS 圧縮ファイルとか、HP-UX のネットワーク特殊
ファイルなどわけのわからんのがありますので、プログラムとしては
    「1〜4 に当てはまらない場合は通常ファイル」
などという仮定はせず、素直に -f を使いましょう。

No. 4590 # 星野 2006/04/23 (日) 18:05:21
UNIX環境のAとBというプロセス間でsocket通信を行っています。(AF_UNIX指定)
一度、ソケットをcloseして、Bが再接続(connect)するとエラーになる場合があります。
errnoが何で返却されているのかわからないのですが。
たとえばEADDRINUSE の場合の対応策を教えて下さい。

No. 4591 # いち 2006/04/24 (月) 21:51:46
番号を昇順に並び替えて、抜けている番号を表示したく、以下の様なシェル
でやってみたのですが、上手く行きません。
どうすればいいでしょうか。
Solaris8 Bシェルです。

sort test.txt | nawk -v key="" '{if(FNR!=0 && $1!=key) print $1 ; key=$1}'
sort test.txt | nawk -v key="" -F"," '{if(FNR!=0 && $1-1!=key) printf("%0.4d\n",key+1); key=$1}'
sort test.txt | nawk -v key="" -F"," '{if(FNR!=0 && $1!=key) printf("%0.4d\n",key+1); key=$1}'

# cat test.txt
0006
0009
0004
0010
0003

結果
0001
0002
0005
0007
0008
と表示したい。

No. 4592 # いち 2006/04/25 (火) 16:52:15
>>4591 いち

nawk -v key=1 '{ for(;;){if($1!=key) {print key; key++;} else{key=$1+1; break;}} }' a.txt
でできました。

No. 4593 # S-MSK☆ 2006/05/01 (月) 14:44:56
>>No. 4588 68user
No.4587のS-MSK☆です。
ご回答有難う御座いました。

No. 4594 # shimizu [E-mail] 2006/05/04 (木) 11:04:32
FTP クライアントを作ってみよう (1) FTP プロトコルの概略

No. 4595 # shimizu [E-mail] 2006/05/04 (木) 11:05:02
>管理人様

FTP クライアントを作ってみよう (1) FTP プロトコルの概略

が大変勉強になりました。ありがとうございました。

No. 4596 # くるみんパパ 2006/05/10 (水) 11:59:59
vmstatをファイルへ出力する時に、1行毎に日時を編集したいのですがうまく出来ません。AIXですと下記のスクリプトでうまくいっているのですがsoralisではどのようにしたらよいでしょうか。

vmstat $1 $2 | awk '!/kthr|---|avm/ {printf("%s | ", $0);system("date")}' >> $LOGDIR$DATE

No. 4597 # zsh 2006/05/10 (水) 13:58:02
>>4596 くるみんパパ
system関数が使いたいのであればnawkか/usr/xpg4/bin/awkを使用してください。

No. 4598 # くるみんパパ 2006/05/10 (水) 14:52:42
>>4597zshさん
nawkで解決しました。助かりました。ありがとうございました。

No. 4599 # 勉強中 2006/05/11 (木) 21:58:28
はじめまして。TCP/IPについて素朴な質問があります。
TCP/IPでは、ACKに対するSYNのタイムアウトがあり、
通常のLINUXであれば180秒ほどだと思います。
一方、telnetで存在しないIPを指定すると上記タイムアウトまでかからず、
以下のメッセージが出て接続できません。

Trying 192.168.60.113...
telnet: Unable to connect to remote host: No route to host

この場合、なぜ上記タイムアウトまで待たないのでしょうか。
telnetコマンドにて
明示的にTCPリトライ回数を指定していると考えていいのでしょうか。
また、このメッセージの意味するところはどういうところなのでしょう?
誰かご存知の方がいたらご教授願います。

No. 4600 # 68user 2006/05/11 (木) 22:19:01
>>4599 勉強中
直接的な回答ではありませんが、
    http://X68000.q-e-d.net/~68user/net/tcp-connect-1.html
をご一読ください。なお、EHOSTUNREACH が No route to host です。

No. 4601 # 勉強中 2006/05/12 (金) 00:22:27
>68userさん
早速のコメントありがとうございます。
要するにアプリケーションの実装によるということですね。
(つまり、ICMP 終点到達不可メッセージを受信した際に、
    ただちにコネクション確立を中止するかしないかというポリシーによるということ)
ちなみにftpでもtelnetと同様でした。

No. 4602 # 68user 2006/05/12 (金) 11:39:16
>>4601 勉強中
> 要するにアプリケーションの実装によるということですね。
いいえ、OS の TCP スタックの実装による、だと思います。

アプリ側で対応する、つまり TCP で接続しつつ、ICMP のエラーを解析という
ことが可能かどうかはやったことがないのでわかりませんが、少なくとも ftp や
telnet という基本的なアプリがそういう小細工をしている可能性は低いと思います。

No. 4603 # 68user 2006/05/13 (土) 19:47:43
>>4602 68user
> アプリ側で対応する、つまり TCP で接続しつつ、ICMP のエラーを解析という
> ことが可能かどうかはやったことがないのでわかりませんが、少なくとも ftp や
> telnet という基本的なアプリがそういう小細工をしている可能性は低いと思います。
ICMP のエラーを解析する必要はなかったですね。connect(2) が -1 を返したとき
EHOSTUNREACH なら再接続、などとすればアプリ側で対応できます。

とはいえ、やはり ftp や telnet がそういうことをする必然性はないと思います。

No. 4604 # COM 2006/05/16 (火) 18:01:08
はじめまして。ネットワークプログラムについて質問させてください。
リミテッドブロードキャスト(255.255.255.255へ)を行いたいのですが、sockaddr_in
のアドレス部分に上記を入れても、何故かディレクテッドブロードキャスト(私の環境
では 192.168.1.255 )になってしまいます。正しくリミテッドブロードキャストする
方法はないでしょうか。setsockopt でブロードキャストのフラグを立てる、などは
行っています。環境は FreeBSD & gcc です。
以下、重要部分の抜粋です(エラー処理などは省いています)。

struct sockaddr_in addr;
int broadcast = 1;
char buf[] = "test";
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("255.255.255.255");
addr.sin_port = htons(2000);
sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast) );
sendto( sock, buf, sizeof(buf), 0, (struct sockaddr*)&addr, sizeof(struct sockaddr) );

ごく普通のコードだと思うのですが、パケットをモニターすると、送り先アドレスが
ディレクテッドブロードキャストになってしまっています。アドバイスだけでもいいので
助言いただけるとうれしいです。

No. 4605 # yuukun 2006/05/25 (木) 15:21:00
はじめまして。sendmailコマンドについての質問です。
[FROM:]や[TO:]フィールドに、アドレスとはべつに別名を指定し実行したところ、
エラーが出力されました。
-------------<実行コマンド>----------------------
sendmail -t
MIME-Version: 1.0
From: hoge株式会社<hoge@hoge.co.jp>
To: huge株式会社御中<huge@huge.co.jp>
Subject: 2006年05月25日の[データ]
Content-Type: text/plain; charset=iso-2022-jp

2006年05月25日 14時53分現在の
データをお送りいたします。
.
------------------------------------------------
TOやFROMフィールドでアドレスとはべつに別名を付けることは可能なのでしょうか?
よろしくお願いします。
OS:Solaris 8

No. 4606 # kojp-jp 2006/05/29 (月) 13:17:45
以下のページの「#inlcude <stdlib.h>」、スペルミスしている様です。

    http://x68000.q-e-d.net/~68user/unix/pickup?getenv

正しくは「#include <stdlib.h>」かと…。

ご確認ください。

No. 4607 # analog 2006/05/29 (月) 13:46:40
初めまして、soralisのC言語について質問させてください
10年以上前にsolalis v4.1で開発してもらったのが
あるのですが、コンピュータ、プリンタが古くなり
最新のものに変えたいとメーカに相談した所
C言語でXVEIWが使われているので最初から作り直しと
なりますといわれました
1.ほんとうに最初からの作りなおしになるのか?
        ソフトはあまり変えず
        現在市販のPC、プリンタを使いたいだけなんですが
        OSは問わない
    
以上なんですが
業者のいいなりになるしかないのか
(修正費用がかなりかかるので)
教えてもらえないでしょうか

No. 4608 # 68user 2006/06/01 (木) 16:48:43
SPAM がウザすぎなので、
    BBQ http://bbq.uso800.net/
を組み込んでみました。BBQ に引っかかると Internal Server Error になります。
書けない場合は書けねぇぞ! と書き込んでください (その際も Internal Server
Error になりますが)。しばらくはログを観察するようにしますので、可能であれば
対処します。

さてうまくいきますかねぇ。

No. 4609 # 68user 2006/06/01 (木) 17:24:53
>>4604 COM
わかりませんが、Linux で動かしてパケットを見ると、255.255.255.255 宛に
飛んでいました。

>>4605 yuukun
> エラーが出力されました。
エラー内容を書きましょう。

>>4606 kojp-jp
getenv と putenv 両方間違っていたので修正いたしました。
ありがとうございました。

>>4607 analog
XView ならば、わたしも同様に言います。理由は以下のとおり。
    - 現在は、XView はほとんど使われていない
    - よってほとんどの開発者には XView の知識がない
    - 勉強しようにも、解説本が売られていない (と思われる)
    - 勉強しても、その知識を他で生かせる可能性が低い

> ほんとうに最初からの作りなおしになるのか?
基本的には OpenWindows 環境がある Solaris10 などでは動くはずですが、
とにかく XView も OpenWindows も時代遅れな環境ですので、修正が必要な
部分はそれなりにあると思われます。

よって XView の技術者がいる会社であれば、修正量・移行リスクを見積もる
ことができ、修正作業も行えるでしょう。

http://business.rakuten.co.jp/ などでそういう会社をがんばって探すか、
作り直しを受け入れるか、です。


ちなみに、わたしが今いる環境には技術者が数十名いますが、おそらく
XView がわかる人はいないと思われます。昔いた会社は UNIX を作って
いたくらいなので探せばいるでしょう。ただし、いたとしても 40〜50歳の
おじさんだと思われます。すでに管理職だったり、工数が見合わなかったりで、
受けたがらないでしょうね。

No. 4618 # COM 2006/06/02 (金) 11:24:28
>>4609 68user
ご返答ありがとうございます。Linux ではそれでうまくいくのですね。
どうしてもダメだったので、rawIP を使い、MAC アドレスを FF:FF:FF:FF:FF:FF に
セットすることで解決しました。ありがとうございました。

No. 4619 # 68user 2006/06/02 (金) 16:31:55
>>4608 68user
BBQ 導入後 24時間で、
    - 成功 20件 (SPAM を SPAM と判定できたケース)
    - 失敗 12件 (SPAM をそのまま通してしまったケース)
でした。それなりにがんばってくれたものの、毎日12件削除するのは面倒。
URLBL のチェックも追加しようかな。

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