コマンドレットのパラメータを列挙してみる。記事のとおり、自分の全ツイートデータをダウンロードする機能がTwitterで利用可能になっています。ダウンロードされるzipファイルには、ツイートを表示するためのHTML、JavaScriptファイルのほか、CSV形式のデータ(tweets.csv)も含まれています。CSVファイルの処理といえばPowerShellが得意とするところです。このファイルを読み込んで、PowerShellで自分のツイートを分析してみましょう。具体的にダウンロードする方法は上記記事を参考にしていただいて、まずはダウンロードしたzipファイルからtweets.csvを解凍し、PowerShellのカレントディレクトリをtweets.csvのあるフォルダに移動させておいてください。毎回CSVを読み込むと時間がかかるので、まず以下のようにしてImport-CsvコマンドレットによりCSVファイルを読み込み、変数にオブジェクトとして入れておきます。tweets.csvなお私の総ツイート数は4万ほどで、tweets.csvは10MB程です。これくらいの容量だとそのままでもまずまずまともな速度で分析が可能ですが、何十万ツイートもしていらっしゃるTwitter廃人マニアの方は、適宜ファイルを分割するなどして対処願います。CSVファイルのヘッダ行は"tweet_id","in_reply_to_status_id","in_reply_to_user_id","retweeted_status_id","retweeted_status_user_id","timestamp","source","text","expanded_urls"となっています。Import-Csvコマンドレットはデフォルトでは1行目を出力オブジェクトのプロパティ名とするので、データ行の1行がtweet_idプロパティ等を持つオブジェクトとして読み込まれ、$tweets変数にはそのオブジェクトの配列が格納されることになります。:Select-Objectコマンドレット(エイリアスselect)はオブジェクトの絞り込みに使います。このCSVファイルではツイートの並び順がタイムスタンプの降順なので、最初のツイートは一番最後の行となります。Speedがなんか懐かしい。いえばEAのシムシティ不具合お詫び無料DL特典、何選ぼうかなあ。シティ4あるけど英語版という噂だし2013やった後につらいもんがありそう。いうわけでシムシティ大好きなんで、私の街を返してください......Format-Listコマンドレット(エイリアスfl)を使うと必要なプロパティ値のみ抽出してリスト形式で表示できます。眠いのってもしかしてアレルギールの副作用かも。眠いなあ...Where-Objectコマンドレット(エイリアスwhere)を使うとオブジェクト配列のうち特定条件のもののみ抽出できます。ここではツイート本文(textプロパティ)に"眠い"という文字列が含まれているものを抽出しています。家族でおせちをたべた。おいしかった...もちろん本文に含まれる文字列以外にも、timestamp(ツイート時刻)で抽出するなどもできます。ここではtimestampがGMTで分かりづらく、かつ文字列のため扱いづらいので、Select-Objectに集計プロパティを指定してDateTime型に変換しています。Format-ListやSelect-Objectに指定する集計プロパティの書式は、@{L="ラベル";E={値を返すスクリプトブロック}}のように連想配列で指定します。LはLabel、EはExpressionのように省略せずに指定してもOKです。集計プロパティはあんまり解説を見かけないですけども、オブジェクトを処理するコマンドレットの多くで利用可能できわめて重要なので覚えておくと良いと思います。$_.timestamp}},text応用でこんなんもできます。0:00:00ちょうどのツイートを抽出します。私はかつてよるほ成功したことがないので結果は何も返ってきませんけど。expanded_urlshttp://ja.wikipedia.org/wiki/%E5%B2%A1%E7%B4%A0%E4%B8%96http://htn.to/4oxXDNhttp://guitarrapc.wordpress.com...whereによる抽出を応用するとこういうこともできます。expanded_urls列は本文中のURLが複数含まれているとそれらは,で区切られるため、可変長の行となります。Import-Csvコマンドレットはこのような可変長なCSVに対応していないので、複数URLがあっても最初の1つのみ取得します。それとexpanded_urlsが追加されたのはt.coによるURL短縮が始まってからなので、昔のツイートにこの値は含まれていません。2012/09...ツイート分析と言えばやはりツイート数統計を取ることから始まるでしょう。統計を取るにはGroup-Objectコマンドレット(エイリアスgroup)が使えます。ここでもグループ化キーとして集計プロパティを指定してやります。ツイートの「年/月」を文字列化し、それが同じツイートでグループ化することで、月別ツイート数の統計が表示できるわけです。23やり方としては先ほどのとほぼ同じです。-ExpandPropertyはパイプライン入力でオブジェクトのプロパティ値を取得できるのでよく使います。プロパティ名」でも取れますね。Sort-Objectコマンドレット(エイリアスsort)でもソートキーとして集計プロパティを指定できます。ここではNameプロパティ(グループ化キーの値)をintに変換したものをキーにソートしています。Saturdayこれもやり方としてはほぼ同じ。ソートキーはDayOfWeek列挙体にキャストしてちゃんと曜日順に並ぶようにしてます。:ここからはツイート数の計測をしていきます。単純にツイート総数を取るだけならMeasure-Objectコマンドレット(エイリアスmeasure)を使うだけでOKです。Averageなどは対応するスイッチパラメータ(-Averageなど)を指定すると計測されますが、この場合は元オブジェクトが数値ではないのでエラーになります。TextLengthツイート文字数を計測するとき、元のオブジェクトにはツイート文字数を返すプロパティはないので、Select-ObjectコマンドレットにTextLengthという集計プロパティを指定して新たに作ってしまいます。Measure-Objectコマンドレットは-Propertyパラメータにより対象オブジェクトのどのプロパティ値を計測するか指定できます。私の総ツイート文字数は183万です。リツイートの場合はretweeted_status_idにリツイート元のツイートIDが入るので、このIDがあるものはWhere-Objectで除外してます。ツイート本文の<や&などはHTMLエンコードされたものがtext列に格納されているので、HttpUtilityを使ってデコードしてから文字数をカウントしています。0.023254609488295Measure-Objectコマンドレットは計測方法を指定することはできないので、独自の計測を行う場合はこんな感じでコードめいたものを書く必要が出てくるかと思います。RT率たったの2%か...ゴミめ...ForEach-Object(エイリアスforeach)は1個のスクリプトブロックをパラメータに指定するとprocessブロック相当の列挙部分を実行しますが、このように3個指定すると、それぞれbegin(初期化処理)、process、end(終了処理)ブロックに割り振られます。ここではbeginブロックで変数初期化、processブロックで通常ツイートとリツイートを加算、endブロックで計測値をPSObjectに格納して出力してます。3.0ではカスタムオブジェクトを作る場合は「[pscustomobject]@{連想配列}」で書くほうが楽です。{$count}137覚えてないから数えます。数値だけを出力するならこんな感じでシンプルに書けますね。twigadge...ここからはいろんなランキングを取得してみます。ツイートに使ったTwitterクライアントのランキング。ここでもGroup-Objectを使っています。クライアント名はクライアント配布URLがaタグで含まれているのでそれを-replace演算子で削ったものをグループ化キーとしています。ランキングなので最後はCountで降順ソート。Countのパターンになるかと思います。リプライツイートはin_reply_to_user_id列にリプライしたユーザーIDが含まれるのでまずはそれでフィルタし、ユーザー名はツイート本文から取ります。ユーザー名は-match演算子を使って正規表現で抽出します。$matches自動変数は連想配列で、[0]にマッチ全体が、[1],[2],...にはサブ式のキャプチャが入ります。ちなみにサブ式に名前を付けてるとキー名が数値ではなくサブ式名となります。#techedj2009...ハッシュタグも同様のアプローチで取れますが、ハッシュタグは1ツイートに複数あることがあり、-match演算子だと複数のマッチは取れないので[regex]を使って取得しています。おわりにPowerShellのオブジェクト処理用コマンドレットを用いると、CSVデータの分析ができます。普通はログファイル等を解析するのに使うわけですが、こういう身近なデータを扱ってみるのも面白いんじゃないでしょうか。PowerShellの勉強にもなると思います。Yamashiro0217の日記ログファイルをコマンド使って解析するというこの課題。Windows?まさか???cygwin入れたり、vmでやってみたり、開発サーバーで作業すればいいんじゃないっすか(ホジホジ)いやいやWindowsでシェルと言えばPowerShellでしょう!というわけでやってみました。出力形式に関しては本筋とは関係ないと思うので、PowerShellのデフォルトのままです。このファイルには重複行がある。-UniquePowerShellはテキスト情報をテキストのまま扱うのではなく、オブジェクトとして扱うところが特徴で、CSVファイルもImport-Csvコマンドレットを用いることで、ヘッダ文字列をプロパティ名として各行をオブジェクトとして読み込んでくれます。あとは各種オブジェクト処理のコマンドレットに、パイプライン経由でオブジェクトを渡していくだけです。コマンドが何をやっているのかも、列番号ではなくプロパティ名を指定してやるので分かりやすいと思います。SQLによる解答例が近いかと思います。今回はCSVから情報を読み込んでいますが、ソースは別になんであってもいいわけです。file.xml)みたいな感じです。オブジェクトとして取得できてしまえば、あとの処理方法は基本的に同じなので悩む必要がないのが良いところです。PowerShellの良いところはやはり、外部処理コマンドを使わずとも、シェル言語と組み込みコマンド(コマンドレット)のみで処理が完結するところです。シェル操作課題への回答のような大変なことになるようです。sortなど基本的なコマンドは使用するにしても、複雑なフィルタ処理などはawkを組みあわせる等しないと、特に後半の処理は辛いでしょう。PowerShellなら異なる処理系を持ち出す必要がなく、PowerShellのみですべて行えます。問題点も色々あります。第一に、今回の課題のように、ヘッダ文字列がないCSVの場合は例のようにヘッダー文字列(=プロパティ名)を自分で定義してやる必要が出てきます。そのため可読性はともかく、若干、冗長なところがでてきてます。例のように一旦オブジェクトを作って変数に入れてしまえばあとは使いまわせますが、そこはちょっと厳しい点かもしれません。あとImport-CsvコマンドレットはCSVの各エントリをすべて文字列型のプロパティとしてオブジェクトに格納するところがちょっと微妙な気がしました。数値は数値型で入れてほしいですよね。おかげで何か所か、[int]にキャストせざるを得ない部分が出てきました。ログファイルが巨大だとかなりリソースを食って時間もかかると思います。処理を分ける、バックグラウンドジョブやワークフローで動かす、そもそもログファイルを分割保存するようにしておく、等、実運用上では工夫が必要かと思います。@mutaguchiBooks書籍版。