Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
11
Help us understand the problem. What is going on with this article?

More than 5 years have passed since last update.

@massa142

tse - Text Stream Editor in Python の紹介

はじめに

この記事はShell Script Advent Calendar 2015 12日目の記事です。

ここでは、石本さん@atsuoishimotoが作成された、Pythonによるテキスト整形ツール「tse」を紹介しようと思います。

実行環境

  • Mac OSX 10.11.1
  • Python 3.5.0

tseとは?

詳しくは今年のPyCon JP 2015で発表されたスライドを見れば、理解できるかと思います。
tse - Pythonによるテキスト整形ユーティリティ

超簡単に言えば、
tseとは、
「ワンライナーに向かないと言われるPythonだけど、やっぱりテキスト処理とかPythonでやりたいよー」
という要望に応えた
「Pythonで sedawk のような処理を実行するためのCLIツール」
です。

pipでインストールできます。

pip install tse

tseの良いところ

  • sys, re, os, os.path は自動インポート
  • 必要なモジュールは指定すれば、実行前にインポート
  • 入出力エンコーディングの指定

あとは実際の処理を見た方がはやいと思うので、幾つか取り上げていこうと思います。
シェル芸勉強会の過去問を使わせて頂きました。

シェル芸勉強会問題にチャレンジ

第17回ジュンク堂はシェル芸が乗っ取った勉強会

Q1

次のようなデータを


$ cat data1
a 1
b 4
a 2
a 3
b 5

次のように変換してみましょう。


a 1 2 3
b 4 5

余力のある人は次のようなJSON形式にしてみましょう。



{a:[1,2,3],b:[4,5]}

解答

  • --beginオプションで、ディクショナリを初期化
  • --endオプションで、ディクショナリのkey, valueをそれぞれ出力すればOK
$cat data1 | tse -b 'd={"a": "", "b": ""}' -s '' 'd[L1] = d[L1] + " " + L2' -e 'for k, v in sorted(d.items()):print(k + v)'
a 1 2 3
b 4 5
  • json形式は、最後にディクショナリをjson.dumps()してやればOK
  • -moduleオプションで、jsonをインポート
$cat data1 | tse -m json -b 'd={"a": [], "b": []}' -s '' 'd[L1].append(int(L2))' -e 'print(json.dumps(sorted(d.items())))'
[["a", [1, 2, 3]], ["b", [4, 5]]]

第18回ニンニク入れますかシェル芸勉強会

Q1

次のファイルは1列目がキー、2列目が値ですが、「オトン」と「オカン」の両方の値があるキーを探してください。


$ cat text 
001 オトン
001 オトン
001 アカン
002 オカン
003 オトン
003 ヤカン
003 オカン
004 オカン
005 オトン
005 ミカン
005 アカン

解答

  • -sオプションで、「オトン」または「オカン」を含むという正規表現を指定すればOK
$uniq text | tse -s 'オトン|オカン' 'print L1' | uniq -d
003

第19回シェル芸3周年記念勉強会

Q2

二つの自然数を


$ echo 1 4

というようにechoで出力したあと、


4
3
2
1
2
3
4

というように間の数を埋めてみてください。

解答

  • ちょっと冗長だが、単純にfor文で繰り返せばOK
$echo 1 4 | tse -s '' 'for s in range(int(L1), int(L2)+1)[::-1]: print(s)' 'for s in range(int(L1)+1, int(L2)+1): print(s)'

おわりに

ざっとtseを活用してみましたが、普段慣れているPythonのsyntaxでワンライナーが書けてお手軽になりました!
怖くて避けていたワンライナーという分野に、少し馴染めることができたような気がします^^

明日の出番は@zayarwinttunさんです!

11
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
11
Help us understand the problem. What is going on with this article?