dポイントプレゼントキャンペーン実施中!

10万行近いファイルについて、
awkを使用して処理を行っているのですが、
何しろ時間がかかります。

改善方法があれば教えていただきたく
よろしくお願いします。

A 回答 (8件)

#7の補足にあるスクリプトだと、


BEGINより前は awkスクリプトじゃないし、最後にある

'>> ALLHOST-REC-"${YEAR}"-"${MONTH}"-"${DAY}"_rsp_JIKEIRETU.csv
done

も awkスクリプトじゃないです。
ここを切らないで a2pに食わせたらそりゃエラーになるのも当然かと。
BEGINの行から ENDの閉じブレースまでを食わせれば

a2p sample.awk >sample.pl
Please check my work on the 2 lines I've marked with "#???".
The operation I've selected may be wrong for the operand types.

警告は出ますがエラーにはなりません。

この回答への補足

ありがとうございます。
ご指摘通り実行した結果、BEGINの行から ENDの閉じブレースまでを
perlに変換できました。

あとは、perlに変換されたファイルをaaa.plとして、
for FNAME in `ls ????????_requrl_ESV_????????.log`
do
cat "${FNAME}" | awk -F , -v syokai_flag=${SYOKAI_FLAG} '
perl aaa.pl
'>> ALLHOST-REC-"${YEAR}"-"${MONTH}"-"${DAY}"_rsp_JIKEIRETU.csv
done
とすれば、よろしいのでしょうか。
よろしくご指導願います。

補足日時:2008/06/07 02:08
    • good
    • 0

>自動生成を行おうとa2p aaa.sh > aaa.perl


を実行したところ、Command Not Found
と出力され、変換できませんでした。
>また、aaa.sh中には、awkでない部分も含まれている
のですが、a2p aaa.sh > aaa.perlとしてよろしいのでしょうか。

まず、a2pがCommand Not Foundになる件ですが、a2pにパスが通っていない可能性があります。
(当方の環境solaris 10(5.10) INTEL版)では、
/usr/perl5/5.8.4/bin/にa2pが入っていました。
もし、その付近にないようでしたら、
ちからわざになりますが、findコマンドでルート(/)からa2pを検索して下さい。(但し、rootユーザの権限が必要ですが)
find / -name a2p とすれば a2pのファイルが検索できます。
みつかれば、そのa2pをフルパスで指定して下さい。
次に、
a2p aaa.sh > aaa.perl としてよいかですが、
これは出来ません。
aaa.sh中のawkの部分を外にだして、aaa.awkという、awk専用の
スクリプトを作成して下さい。
そのあとで、
a2p aaa.awk > aaa.pl (通常、perlの拡張子は.plにします)
として下さい。
これで、aaa.awkからaaa.plが作成されます。
aaa.plの呼び出しは、perl aaa.pl とすればできます。

この回答への補足

ありがとうございます。
a2pについては、ご指摘通り実行し、
短いawkスクリプトはperlスクリプトに変換できました。
しかし、自分の作成したプログラムについては、
Syntax Errorが発生し、うまく変換できません。
どのようにすれば良いのか教えて下さい。
下記に、対象のプログラム(文字制限から一部省略)を
記載しました。お手数ですが、よろしくお願い致します。

for FNAME in `ls ????????_requrl_ESV_????????.log`
do
cat "${FNAME}" | awk -F , -v syokai_flag=${SYOKAI_FLAG} '
BEGIN{
end_f = 0;
time_count = int(24 * 60 / interval);
if (int(24 * 60 % interval) != 0){
time_count = time_count + 1;
}
item_count = 0;
}

{
if (end_f == 0){
if (NF == 1){
if (substr($1,1,4) == substr(date,1,4)){
time = substr($1,12,2) * 60;
time_pos = int(time / interval) + 1;
}
else{
end_f = 1;
}
}
else if ($1 != "index"){
find_f = 0;
}
}
}

END{
for(item_pos = 1;item_pos <= item_count;item_pos++){
for(time_pos = 1;time_pos <= time_count;time_pos++){
printf(",%s",max[item_pos,time_pos]);
if (item_max_max < max[item_pos,time_pos]){
item_max_max = max[item_pos,time_pos];
item_max_max_pos = time_pos;
}
}
printf(",*****,%s",item_max_max);
}
}'>> ALLHOST-REC-"${YEAR}"-"${MONTH}"-"${DAY}"_rsp_JIKEIRETU.csv
done

補足日時:2008/06/06 01:38
    • good
    • 0

a2pはawkスクリプトを変換するものであって、シェルスクリプトを変換するものじゃありません。



perlが入っているのなら、perldoc a2p で詳しいヘルプが読めます。

NAME
a2p - Awk to Perl translator

SYNOPSIS
a2p [*options*] [*filename*]

DESCRIPTION
*A2p* takes an awk script specified on the command line (or from
standard input) and produces a comparable *perl* script on the standard
output.

{
   (省略)  
}
END{
   (省略)  
}'

肝心なところが省略されてますがな。
さらせないものならそのまま貼り付けなくてもいいですけど
どういう処理をしているかの概略くらいは。

まあ全体の構成からすると連想配列にデータを溜め込んでから
最後にそれを使って何かやるんでしょうね。
であれば Perlに置き換えることで速くなる可能性はありますね。
awk以外でごちゃごちゃやってるのも Perlで書けるでしょう。
もっともそれをやってくれるトランスレータはないでしょうけど。

この回答への補足

for FNAME in `ls ????????_requrl_ESV_????????.log`
do
cat "${FNAME}" | awk -F , -v syokai_flag=${SYOKAI_FLAG} '
perl aaa.pl
'>> ALLHOST-REC-"${YEAR}"-"${MONTH}"-"${DAY}"_rsp_JIKEIRETU.csv
done
としたところ、
awk:ファイル"[command line]":行1:構文エラー
が発生しました。
(aaa.plはa2pによりperlに変換した部分です。)
どのようにすればよろしいのでしょうか。
教えて下さい。よろしくお願いいたします。

補足日時:2008/06/11 01:47
    • good
    • 0

こんにちは。



ANo.1 さんのおっしゃる通り、背景情報の補足が期待されます。

(回答者のコメント)

回答者も一ヶ月間のログの解析作業のために二桁万行のボリュームを相手に Awk を使用した経験があります。
    • good
    • 0

perlで実行されては、いかがでしょうか。


perlには、a2p (AWK to perl)というコマンドがあり、AWKのスクリプトから perlのスクリプトを自動生成してくれます。
a2pで自動生成されたスクリプトをperlで実行すれば、速くなる可能性があります。
今回のケースが、どのくらい速くなるかは、保証できませんが、以前、AWKで処理していて、遅かったのをperlに変えて、かなり速くなった記憶があります。

この回答への補足

ありがとうございます。
perlで実行することにしました。
現在、Solaris(SunOS 5.9)上でシェル(aaa.sh)を実行しており、
その内容は、
#!/bin/bash
for FNAME in `ls ????????.log`
do
HOSTNAME=`echo "${FNAME}" | cut -b1-8`
cat "${FNAME}" | awk -F , '
BEGIN{
(省略)
}
{
   (省略)  
}
END{
   (省略)  
}' > "${HOSTNAME}".rsl
done
といった感じです。
処理内容としましては、
ログファイル(????????.log)から、
最大や平均を求め、
結果ファイル(????????.rsl)に出力するものです。

ところで、perlは入っているようですが、
自動生成を行おうと
a2p aaa.sh > aaa.perl
を実行したところ、
Command Not Found
と出力され、変換できませんでした。
また、aaa.sh中には、awkでない部分も含まれている
のですが、a2p aaa.sh > aaa.perl
としてよろしいのでしょうか。
自動生成について、その詳細を教えて下さい。
よろしくお願いします。

補足日時:2008/06/05 00:41
    • good
    • 0

Cでプログラム作ればawkより圧倒的に速いと思います。

    • good
    • 0

少なくとも、どんなスクリプトを書いて何を実行していて遅いのかがわからないと、何も言えないです。


「マシンの性能を、考えられる最高のものにしてください」とかになりますかね。それでもどの程度の効果があるかわかりませんが、例えば 32bit x86のunixサーバから、sun sparc64 VIの128 cpu くらいに変更したら、きっと目に見えて効果があると思いますけど。
    • good
    • 0

今現在どのようなことをどのようにやっているかの情報もなしに


アドバイスできる人はそうそういないんじゃないでしょうか。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!