こづかい帳作成の注意点と時間データの集計方法

このQ&Aのポイント
  • こづかい帳作成時の注意点として、センセーショナルなタイトルを30文字前後で生成する必要があります。また、質問文章の内容を要約し、100文字程度の要約文を3つ作成する必要があります。さらに、時間データを集計する際には、データの重複を回避するために注意が必要です。
  • データの重複を回避するための方法として、uniqコマンドを使用することが考えられます。ただし、uniqコマンドを実行する際には、集計前にデータを追加する必要もあります。具体的には、時間のデータが重複する場合は、重複したデータを削除するという処理を行うことができます。
  • しかし、uniqコマンドを使用する際には注意が必要です。uniqコマンドを実行した段階で重複したデータが削除されてしまうため、必要なデータが失われる可能性があります。そのため、uniqコマンドを実行する前に、重複したデータを追加することを検討する必要があります。
回答を見る
  • ベストアンサー

またまたこづかい帳です~

こんばんは。こづかい帳作っててまた分からなくなっちゃいました。 環境はgawkとbashを用いてlogの集計を行っています。 1/1 gohan 1000 1/1 kaimono 5000 1/1 kaimono 2000 1/2 karaoke 3500 1/2 gohan 1200 1/2 gohan 1500 前回このようなlogを元に集計しました。おかげ様で 1/1 gohan 1000 1/1 kaimono 7000 1/2 karaoke 3500 1/2 gohan 2700 このように集計することが出来ました。ありがとうございます。 でも、ここで時間も入れることにしました。その代わり日付はいりません。 それは一日一回logを集計して、終わったら元データを消すことにしたからです。 07:00 gohan 500 11:00 kaimono 2000 12:00 gohan 1000 15:00 oyatu 300 19:00 gohan 2000 というのがありまして、これを 00:00 0 0 01:00 0 0 02:00 0 0 03:00 0 0 04:00 0 0 05:00 0 0 06:00 0 0 07:00 gohan 500 08:00 0 0 09:00 0 0 10:00 0 0 11:00 kaimono 2000 12:00 gohan 1000 13:00 0 0 14:00 0 0 15:00 oyatu 300 16:00 0 0 17:00 0 0 18:00 0 0 19:00 gohan 2000 20:00 0 0 21:00 0 0 22:00 0 0 23:00 0 0 という風にすることは出来るんですか?これをしようとした時に 初めから元のデータに 00:00 0 0 01:00 0 0 02:00 0 0 続く 22:00 0 0 23:00 0 0 を追加してみて、時間のところが重複したら消すとかやるのかな~と 思ったんですが、そのことを先生に話したら、勝手にデータに追加するなんて ナンセンスだ!って言われちゃいました。それはそうですよね。。。^^ でもuniqコマンドってありますよね。このやり方でも出来ますか? uniqコマンドして$2>0なら消す。。。あれ?uniqコマンドした時点で 消えちゃってるや。。。ダメじゃ~ん(笑)分かる方教えて下さいな~

質問者が選んだベストアンサー

  • ベストアンサー
  • terra5
  • ベストアンサー率34% (574/1662)
回答No.1

今回は、何がしたいのかがよくわかりません。 見たところ,集計もせずにデータを増やしているだけですし。 単に、1時間単位で出力して、データが無ければ 0 を出すというのは作れますが,意味がなさそうなのでやる気はありません(^^;;; 結局、月ごとに集計するのなら、無駄なデータを追加するだけですし。 まずは、何のために、どういうものをつくりたいのかはっきりさせましょう。

heikekaori
質問者

お礼

あれ。なんかterra5さんが補足した形になっちゃいました。 ごめんなさい。

heikekaori
質問者

補足

お返事ありがとう。 うーん、全くその通りですね(^^; ただ単にデータを増やしているだけだ~(>_<) 「何のためにどういうものをつくりたいのか」だけど、 「こづかいの集計機能の体得のために」 「logを集計してグラフで分かり易くしたい」 です。グラフは集計後のlogをftpを使って自分のパソコンに取り込んで、 Excelでグラフ化するつもりです。でも、 ほんとはね、集計する時にちゃんと1時間づつ区切って 24個のlogを作るつもりだったんだよ。 でも、分からなかったの。あ、違う。えーとー、 { for(i=1;i<=24;i++){ if((100*(i-1) <= $1) && ($1 < 100*i)){ count[i]++ } } } END{ for(i=1;i<=24;i++){ if(count[i] != 0){ print i,count[i] } else { print i,0 } } } ってやると、データがない時に0出るよね?でも、集計する時に { if(length($2) > 0){ kazu[$2] ++; } } END{ for(i in kazu) print $1,i,kazu[i] } ってのを使う場合、for文ってのは同じだけど、これってawk独特の 連想配列ってやつとかで、これと先に書いたfor文を組み合わせることが できないんです。それか、前に教えてもらった { sum[$2,$3] += $4 } END { for(item in sum){ split(item, t, SUBSEP ); printf("%s %s %s %d\n",$1,t[1],t[2],sum[item]); } } これだって、連想配列ですよね?結局、集計が終わってから 「あ、0のデータがない…。」って気付いて、 後から0のデータをくっつけるってことになっちゃったんです。 どうしたらいいですか~?あ、今考えてる方針、 自分が思ってるの言います。時間のフィールドで 23:00だったら、FS=":"ってやってjikan=$1*3600ってやれば 秒数が出ますよね。ここでまた新たに for(i=1;i<=24;i++){ if((3600*(i-1) <= jikan) && (jikan < 3600*i)){ print strftime("%H:%M",jikan),$2,$3 } else { print strftime("%H:%M",jikan),0,0 } } ってやればいいんですか?

その他の回答 (2)

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.3

らちがあかないので、そろそろ逃げます(^^;; やろうとしていることをうまく文章にまとまめられないと、こういう場では私には対応は無理です. また、文章でないにしても、具体的にこういうデータでこういうスクリプトで処理するとこうなったが、 どこを直せばよいかとか. 今のだと、入力データも出力結果も実際に使ったスクリプトも判らなくて,判断できません. 現状だと、おそらく直接会っていろいろ話ながら数時間かかると思います。 前回の内容からすると,やることが飛躍的に増えすぎていて収集つかなくなっているようにも感じますので、 もう少しやりたいことを絞り込んでやり直したほうがいいと思います.

heikekaori
質問者

お礼

うん。ありがとね。色々教えてくれてほんと嬉しかったよ☆ 残念だけど(:_;)またいつか整理して現れます~♪ ほんとにさんきゅ~~~~~ PS.同じ人に「良回答」と「次点」どっちも付けられないんだね。   terra5さんに気持ちの上では30POINT!!!

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.2

まずは目的から. >「logを集計してグラフで分かり易くしたい」 どういうグラフを作りたいのでしょうか? 今回のは時刻ごとに使った金額を集計して、それをグラフ化したいということでしょうか? >それは一日一回logを集計して、終わったら元データを消すことにしたからです。 これももっと明確にしないとプログラムはできません。 どういった集計をして、どういう形のデータをつくるのが不明です。 文章中で個々に気になる点を。 > if((100*(i-1) <= $1) $1には例えば"01:00"が入っていますよね? これと数値を比較するのは好ましくないと思います. 通常は,ここから"01"の部分だけを数値化して比較するのが正しいでしょう. >if(length($2) > 0){ $2は例えば,"0"とか"gohan"がはいりますよね? 何のための処理かわかりません。 >awk独特の連想配列ってやつとかで、これと先に書いたfor文を組み合わせることが >できないんです。 連想記憶はperlにもあります。 また、forの組み合わせが出来ないと言う意味もわかりません。 どういうことがやりたいのか判らないので,答えられません. >23:00だったら、FS=":"ってやってjikan=$1*3600ってやれば >秒数が出ますよね。 行の内容が"23:00 0 0"の場合、FS=":"とすると $1=="23" $2=="00 0 0"になりますが、問題ありませんか?

heikekaori
質問者

お礼

>>「logを集計してグラフで分かり易くしたい」 >どういうグラフを作りたいのでしょうか? >今回のは時刻ごとに使った金額を集計して、それをグラフ化したいということ >でしょうか? そうですね。何かうまく伝わらないようでたびたびすみません。 時刻ごとに使った用途と金額の表が元になって、 棒グラフでOKです。 >>それは一日一回logを集計して、終わったら元データを消すことに >>したからです。 >これももっと明確にしないとプログラムはできません。 >どういった集計をして、どういう形のデータをつくるのが不明です。 えーと、これは。一日一回cronにお願いして、0:00ちょっと前 (23:58ぐらいの予定なんですが)に元データを削除し、 また最初からデータを取り始める。だから、日にちの部分は システム時刻から持ってくればいいかなって。 >> if((100*(i-1) <= $1) >$1には例えば"01:00"が入っていますよね? >これと数値を比較するのは好ましくないと思います. >通常は,ここから"01"の部分だけを数値化して比較するのが正しいでしょう. あ、これはすみません。この連想配列の部分だけは 適当にサンプルから持ってきたものです。数値と時刻を 比較するつもりはありませんのです。 >>if(length($2) > 0){ >$2は例えば,"0"とか"gohan"がはいりますよね? >何のための処理かわかりません。 これは、「$2に文字列があったら」って意味です。 「gohan」これは間違いなく文字列ですよね。その時は カウントする。また「karaoke」についても 別の連想記憶で(?)カウントする。 END文でカウントしたのをprintするってつもりなの。 >>awk独特の連想配列ってやつとかで、これと先に書いたfor文を >>組み合わせることができないんです。 >連想記憶はperlにもあります。 >また、forの組み合わせが出来ないと言う意味もわかりません。 >どういうことがやりたいのか判らないので,答えられません. 連想配列(連想記憶?)って言うのは、for文ですよね。 あ、for文じゃなくてもいいのかな。count[i]のようにして count[1]、count[2]、count[3]…。にそれぞれ値を入れるってことですよね? これとfor(i=1;i<=24;i++)というfor文は区別されるんじゃないんですか? 構文の使い方が違いますよね?私は連想配列って言うのを、 多種の項目(gohanとかkaraokeとか)それぞれの個数を、カウントすることが 出来る構文として知り始めたんです。だからなのか、for(i in count)形式の ものとfor(i=1;i<=24;i++)の形式のものを区別して考えてしまいます。 例えば10行のlogがあったとしますよね。ここでfor(i in count)形式を 使いカウントをしたとしますよね(カウント以外にもあるんだろうけど)。 結果、出力されるlogって言うのは10行以下ですよね(集計されて)。 これは集計が行われたと言えると思います。じゃ、for(i=1;i<=24;i++)形式を 使用して、if(((i-1) <= $1) && ($1 < i))にあてはめるとすると、 iが1の場合について10回処理。2の場合について10回処理。 結果、240行以下のlogが出力される。if文のelse部にprintを使ったり しなければ、for(i=1;i<=24;i++)形式同様10行以下の出力になるでしょうけど、 私は今、0:00の行にgohanがなかったら、0 0とくっつけたいわけですから、 else文にその場合を書くことになりますよね。すると、iが1の時、2の時、 それぞれについて10行出力されてしまうわけで、結局やっぱり 240以下のlogが出力されてしまいます。そうすると 00:00 0 0 00:30 karaoke 1500 00:30 0 0 01:00 0 0 ということになっちゃいまして、 その場合は00:30 0 0の部分は不要なんですよ。 だから、これを消すのかなって思ったんです。 例えば、for(i in count)形式とfor(i=1;i<=24;i++)形式が 同じブロック内とか、メインループとENDブロックとか、 そのように使われている例とかありますか? それって可能なのですか?うーん、うまく言えません。 07:00 gohan 500 11:00 kaimono 2000 12:00 gohan 1000 15:00 oyatu 300 19:00 gohan 2000 このように出力するのは、 { sum[$2,$3] += $4 } END { for(item in sum){ split(item, t, SUBSEP ); printf("%s %s %s %d\n",$1,t[1],t[2],sum[item]); } } これを使いました。この時点で、 { for(i=1;i<=24;i++){ if((3600*(i-1) <= jikan) && (jikan < 3600*i)){ print strftime("%H:%M",jikan),$2,$3 } else { print strftime("%H:%M",jikan),0,0 } } これのように$2が一致しなかったら0 0を返して、 00:00 0 0 01:00 0 0 02:00 0 0 03:00 0 0 04:00 0 0 05:00 0 0 06:00 0 0 07:00 gohan 500 08:00 0 0 09:00 0 0 10:00 0 0 11:00 kaimono 2000 12:00 gohan 1000 13:00 0 0 14:00 0 0 15:00 oyatu 300 16:00 0 0 17:00 0 0 18:00 0 0 19:00 gohan 2000 20:00 0 0 21:00 0 0 22:00 0 0 23:00 0 0 というのを出力させることは可能ですか? >>23:00だったら、FS=":"ってやってjikan=$1*3600ってやれば >>秒数が出ますよね。 >行の内容が"23:00 0 0"の場合、FS=":"とすると >$1=="23" $2=="00 0 0"になりますが、問題ありませんか? 問題ないと思うんですが…。$1が23なんですから、 jikan=23*3600ってなって、23:00を見事に秒数に変換出来たって 言えるんじゃありませんか?それをファイルに入れると、 $1は82800になり、ここで改めて { for(i=1;i<=24;i++){ if((3600*(i-1) <= $1) && ($1 < 3600*i)){ print strftime("%H:%M",$1),$2,$3 } else { print strftime("%H:%M",$1),0,0 } } に当てればいいのかなって。 分からないところだらけだろうとは思うんですが、 私も一応必死になって説明してるつもりなんです。 またご指摘頂ければ、もっと頑張って状況説明します。 だからなんとかお願いします。長くてほんとごめんなさい。

関連するQ&A

  • こづかい帳のような集計のアルゴリズムって?

    こんばんは。gawkとbashを用いてlogの集計を行っています。 その際にお小遣い帳のような機能を実現することがなかなか出来ずに 困っています。perlだったら、ネットでもかなり情報が豊富だし、 書籍も多いと思うけど、awkってUNIXの基本的な知識ってことでUNIX管理系の 書籍にちょこっと載ってるってケースが多いですよね。それか ものすごく分厚い本でなかなかなじめないようなのとか。。。助けて下さい。 例えば 1/1 gohan 1000 1/1 kaimono 5000 1/1 kaimono 2000 1/2 karaoke 3500 1/2 gohan 1200 1/2 gohan 1500 といったデータがあったとして、これを 1/1 gohan 1000 1/1 kaimono 7000 1/2 karaoke 3500 1/2 gohan 2700 のように集計したいのです。月日の部分を基点にして、1/1の部分についてだけ for(i in count)の形式を用いて集計する。その後1/2の部分について集計する。 というのをずーっと続けていくには、どのようなスクリプトを書けば いいんですか?教えて下さい。どうかお願いします。

  • VB2005で重複件数を調べたい

    VB初心者ですがUNIXコマンドの『uniq -c』のような重複件数を 出力して重複行を1行だけ出力したいのですがどう書けばよいのでしょうか? 【DATA】 3010 3020 3010 3011 3010 【処理結果】 3010,3 3011,1 3020,1 ご教授おねがいします。

  • awkで列を集計するシェルについて

    シェル初心者です。教えてください。 ログファイルが10万行超えるものでシェルにて集計することになり、下記のような集計ができればと思っています。 商店名 商品名  価格 A商店 りんご   100 B商店  ぶどう 300 A商店  みかん 150 C商店  りんご 100 A商店  りんご 100 B商店  みかん 150 C商店  りんご 100 C商店  ぶどう 300 ※各列はブランク(空白)によって区切られ、改行済みで行数は10万行以上 (1)awk '{print $1}' | uniq -d (重複した商店の抽出) (2)awk '{print $2}' | uniq -d (重複した商品名の抽出) (1)、(2)の抽出を満たす「価格」の合計を"集計結果”として > shukei.txt などに出力したいと思ってます。 VBAでいれば、firlterしsumifして合計するようなイメージのものです。 ご教授お願い致します><

  • Linuxコマンドのエラーについて

    こんにちは。会社の前任者より引継ぎ、初めてのLinuxコマンドに苦戦しています。 tracklist.csvというファイルの中に、8桁の数字が上から下に向かってたくさん入力されています。 その中から重複データを抽出するために、Cygwinというツールで以下のコマンドを入力し、duplicate.txtに重複データを抽出しようとしてますが、データが0件でファイルが抽出されます。 $ cat tracklist.csv l sort -n l uniq -d >duplicate.txt cat: invalid optin --d Try 'cat --help' for more information 重複データは必ず含まれているはずですので、Hitしないはずがないのですが。。。。 説明が少なく申し訳ございません。これで原因がわかるようでしたら、回答を教えてください。 よろしくお願いいたします。

  • UNIXで文字列操作

    あるログファイルを整理しているのですが知識が無く困ってます。 A A B C というログファイルの重複部分のみ消去したいのですが一般的なコマンドで可能でしょうか?catしてsortして整理まではできたのですが重複文字列をどのように消せば良いでしょうか? データ数は2万行ほどです

  • webalizerのログを再集計したいのですが・・

    知人に頼んで、サイトのアクセスログ解析にwebalizerを使用して毎日決まった時間に集計するよう設定してもらいました。 ある日うまくログ解析できなかったため、自分なりに調べてwebalizerを実行した所、一部の集計データが消えてしまいました! 具体的な状況は以下になります。 8月9日に8月8日のログが集計されていない事を確認 ※この時点で8月1日~7日の集計データは表示されていました。 ↓ webalizerの再実行 ↓ 8月8日の集計データは表示されたが、8月1日~7日の集計データが消失。 ↓ 現在は正常に作動中。但し8月1日~7日は消えたまま、8日以降のデータしか表示されない。 なんとかログを再集計して、8月1日~7日のデータを表示したいのですが どのようにすればよいでしょうか? webalizerはぜんぜん理解していないため、非常に困っております・・・。

  • CSVファイルの重複チェック

    あるデータがあり、そのデータが毎日増えていくと仮定します。 (もともと元データが100件あって、毎日10件づつ増えていくようなイメージ) 毎日10件づつ増えていくデータの中で、もともとあった100件と 重複しているものがあるかどうかのチェックを効率的に行いたいと考えています。 イメージとしては元データはaccessかエクセル上に存在していて、 毎日増えていくデータをCSVインポートか何かで取り込んで、 マクロか何かでチェックをかけると、 重複しているかどうかのチェックをかけてくれるような仕組みが無いか探しています。 (重複していないものの一覧をエクスポート および 重複していないものを元データに追加してくれる とかいう処理があるとよりありがたいです) 手動でやると大変なので、そういったことが出来るツールなど フリーソフトでご存知の方、もしくはエクセルマクロで簡単に出来るよ といったアドバイスいただけると大変助かります。 WEBシステムでももちろん結構です。 質問の中で不明確な点がありましたら追加で補足しますのでご指摘ください。

  • 自宅の公開サーバへのアクセス元IPの解析を以下のスクリプトで行おうと考

    自宅の公開サーバへのアクセス元IPの解析を以下のスクリプトで行おうと考えております。 これをcronで自動化したいのですが、cronで実行するとawk以下のコマンドの実行結果が空になり、本文に組み込まれません。日本語は正しく表示されています。 rootで実行した場合は、すべての結果が正しくメール送信されてきます。 Linux初心者なため、詳しい方からのアドバイスをお待ちしております。 以上、よろしくお願いいたします。 ~~~~~~スクリプト~~~~~~~~~ #!/bin/bash # 初期設定(環境変数、メール送信宛先、件名、コマンド) export LANG=ja_JP.UTF-8 address="hogehoge@hoge.com" subject="Webアクセス解析" LOG=./log/http_analyze.log cmd="cat $LOG" awk '{print $1}' /var/log/httpd/access_log | sort | uniq -c | sort -r > $LOG 2>&1 # 件名の文字コードをJISに変換 #subject=`echo $subject | nkf -j` subject=`echo $subject` # メール送信(コマンド結果はSJISに変換) mail -s "$subject" $address << HONBUN アクセス回数/アクセス元IPアドレス `$cmd` HONBUN # 終了 exit ~~~~~~~~~~~~~~~~~~~~ ~~~~root実行結果メール本文~~~~ アクセス回数/アクセス元IPアドレス 34 192.168.0.XXX 12 84.XXX.181.XXX 8 201.XXX.235.XXX 6 187.XXX.19.XXX ~~~~~~~~~~~~~~~~~~~ ~~~~cron実行結果メール本文~~~~ アクセス回数/アクセス元IPアドレス ~~~~~~~~~~~~~~~~~~~ また、その他気になる点がありましたら、合わせてアドバイスいただければ幸いです。

  • キーが重複したレコードを無視してリストアする方法は?

    キーが重複したレコードがバックアップファイル内にあっても、それを無視して重複していないレコードだけをリストアする方法は無いでしょうか? 現在、osqlコマンドを用いてテーブルの既存データに追加する形でリストアするプログラムを作っているのですが、重複したレコードがあると処理が中断してしまうため、残った重複のないレコードを追加できずに困っています。 サーバはSQL Server 2000 使用言語はVB.NET になります。 ご教授宜しくお願い致します。

  • ピボットテーブルについてです

    ピボットテーブル内のデータで件数を数えたいのですがそれは可能でしょうか? 例えば画像のようなピボットで、「何月にA社では何種類売り上げがあったか」を出したいです。 できれば、集計行の上下どちらかに結果を出したいです。 元データを使っていろいろしてみましたが、重複するデータが多いので正しく出せません。ピボットのデータで…と思うのですが、可能でしたら方法を教えていただきたいです。 図々しいですが、もし他に方法があれば、教えていただきたいです。