読者です 読者をやめる 読者になる 読者になる

シェル操作課題をPythonでやってみた

python

はてブのマイホットエントリーを眺めてたらこんなものを見つけた。
シェル操作課題 (cut, sort, uniq などで集計を行う) 設問編 - Yamashiro0217の日記
awkとか全然知らないから勉強になるかなと思って覗いてみたんだけど…

いっそpythonワンライナーで実行したらカッコイイと思うw

やりましょう

Python3.2でやってみたよ

問1 このファイルを表示しろ
$ python3 -c "import functools,operator;print(functools.reduce(operator.__add__, (open('hoge.csv','r').readlines())))"

server1,1343363124,30,/video.php
server2,1343363110,20,/profile.php
server3,1343363115,7,/login.php
server1,1343363105,8,/profile.php
server2,1343363205,35,/profile.php
server2,1343363110,20,/profile.php
server3,1343363205,30,/login.php
server4,1343363225,12,/video.php
server1,1343363265,7,/video.php

問2 このファイルからサーバー名とアクセス先だけ表示しろ
$ python3 -c "import csv,operator,functools;print(functools.reduce(operator.__add__, [','.join((r[0], r[3]+'\n')) for r in csv.reader(open('hoge.csv','r'))]))"

server1,/video.php
server2,/profile.php
server3,/login.php
server1,/profile.php
server2,/profile.php
server2,/profile.php
server3,/login.php
server4,/video.php
server1,/video.php

問3 このファイルからserver4の行だけ表示しろ
$ python3 -c "print([line for line in open('hoge.csv','r').readlines() if line[6]=='4'][0])"

server4,1343363225,12,/video.php

問4 このファイルの行数を表示しろ
$ python3 -c "print(len(open('hoge.csv','r').readlines()))"

9

問5 このファイルをサーバー名、ユーザーIDの昇順で5行だけ表示しろ
$ python3 -c "import operator,csv,functools;print(functools.reduce(operator.__add__, [','.join((r[0],str(r[1]),str(r[2]),r[3])) for r in sorted([(r[0], int(r[1]), int(r[2]), r[3]+'\n') for r in csv.reader(open('hoge.csv','r'))], key=operator.itemgetter(0,2))][:5]))"

server1,1343363265,7,/video.php
server1,1343363105,8,/profile.php
server1,1343363124,30,/video.php
server2,1343363110,20,/profile.php
server2,1343363110,20,/profile.php

これが一番ひどい。数値としてソートするためにintに変換して、その後文字列連結するためにintにしたものをstrに直してる。

問6 このファイルには重複行がある。重複行はまとめて数え行数を表示しろ
$ python3 -c "print(len(set(open('hoge.csv','r'))))"

8

問7 このログのUU(ユニークユーザー)数を表示しろ
$ python3 -c "import csv;print(len(set([r[2] for r in csv.reader(open('hoge.csv','r'))])))"

6

問8 このログのアクセス先ごとにアクセス数を数え上位1つを表示しろ
$ python3 -c "import csv,collections;print(collections.Counter([r[1] for r in set([(r[2],r[3]) for r in csv.reader(open('hoge.csv','r'))])]).most_common(1))"

[('/video.php', 3)]

表示がちょっとアレだけど、知りたい情報が取り出せてるしこれでいいよねもう。

問9 このログのserverという文字列をxxxという文字列に変え、サーバー毎のアクセス数を表示しろ
$ python3 -c "import csv,collections;print(collections.Counter(map(lambda x: x.replace('server', 'xxx'), [r[0] for r in csv.reader(open('hoge.csv','r'))])))"

Counter({'xxx1': 3, 'xxx2': 3, 'xxx3': 2, 'xxx4': 1})

これまた表示が形式が違うけどこれでいいよね。ていうか出題者の想定結果が間違ってる気がするんですが。

問10 このログのユーザーIDが10以上の人のユニークなユーザーIDをユーザーIDでソートして表示しろ
$ python3 -c "import csv;print(set([r[2] for r in csv.reader(open('hoge.csv','r')) if int(r[2]) >= 10]))"

{'12', '30', '20', '35'}

これまた表示が(ry

感想

Pythonワンライナーなんてやるもんじゃない。