tse Text Stream Editor
Pythonによる
テキスト整形ユーティリティ
2015/10/10 PyCon JP 2015
Atsuo Ishimoto
自己紹介
2
いしもと
石本 敦夫
あつお
python.jp ドメインの管理者
@atsuoishimoto
著書
Pythonライブラリ厳選レシピ
Python文法詳解
パーフェクトPython
Unixのテキスト処理といえば
3
sed, awk, perlなどのワンライナーが定番
Pythonでもワンライナーを書きたい
使い慣れたモジュール群を手軽に活用したい
いちいちスクリプトファイルを作成したくない
シェルのヒストリーか...
Pythonはワンライナー向き?
4
向きません
インデントと改行が必須
sys, reなどのimportなど、タイプ量が多い
ワンライナー用のコマンドラインオプションがない
 (Python2) Unicode(Encode|Deco...
tse Text Stream Editor
5
Pythonによるテキスト整形ツール
Pythonスクリプトをコマンドラインで指定
一般的なモジュール(sys, reなど)の自動イン
ポート
ファイルを読み込み、スクリプトを実行
入出...
インストール方法
6
pip install tse
Python2.7以降
Python3.3以降
tseの動作
7
1. テキストファイルを一行ずつ読み込み、
2. 行に一致するパターンがあれば、
3. 行を変数に代入し、
4.対応するアクションを実行する
$ tse -s '^d+' 'print(L.lower())' 
-s '^w+' 'print(L.upper())'
パターンとアクション
8
パターン 入力行を検索する、正規表現式
アクション パターンの検索が成功した時に実
行す...
サンプル
9
'spam' を含む行を、小文字に変換して出力
tse -s "spam" "print(L.lower())" < s.txt
サンプル
10
行ごとに、すべての数字列の和を出力
tse -s ".*" "print(sum(int(s) for s in
re.findall(r"d+", L)))"" < s.txt
パターン
11
例
• spam|ham 'spam' または 'ham' を含む行
• ^d+ 数字列で始まる行
reモジュールを利用
入力テキストを検索する正規表現式
アクション
12
例
• print('hello') 'hello'と出力
• print(L.upper()) 行を大文字に変換して出力
パターンがヒットした行で実行するスクリプト
複数行のアクション
13
例
$tse -s '^w' 'if L:' ' print(L)' < spam.txt
パターンには複数のアクションを指定できる。
2番目以降のアクションは、先頭のアクション
の次の行として実行される。
if L:...
インデント
14
$ tse -s '.*' 'if len(L)>5:{{print(1)}}'
{{ と }} でインデントするブロックを指定する
if len(L)>5:
print(1)
文字列・コメント中の"{{}}" はインデントと...
入力ファイルの指定
15
-s オプションに続けてファイル名を指定するとき
は、オプションとファイル名を -- で区切る
ファイル名が - のときは、標準入力から読み込む
$tse -s '^d' 'print(S)' -- a.txt b.t...
変数
16
処理中のテキストは、変数に格納される
変数名 内容
L 現在処理中のテキスト行全体
L0 テキスト行を空白で区切った文字列の
配列
L1, L2,... テキスト行を空白で区切った文字列の
1番目、2番目、…
N L0の長さ
マッチ文字列
17
正規表現にマッチした文字列も変数に格納
変数名 内容
S 正規表現にマッチしたグループの配列
S0 正規表現にマッチした部分文字列全体
S1, S2,... ()で囲んだグループの部分文字列
グループ名 '(?P<グループ名...
変数のサンプル
18
$ echo 'ab cd ef'| tse -s '.*' 'print(L3, L2, L1)'
ef cd ab
空白区切りの単語を出力
$ echo '123abc' 
| tse -s '(?P<num>d+)(...
変数のサンプル
19
$ls -l|tse -s '' 'if N>2 and int(L5)>=1024:print(L9)'
サイズ>=1024のファイル名を出力
$ ls -l
total 168
-rw-r--r-- 1 ishimot...
その他の変数
20
変数名 内容
FILENAME 処理中のファイル名。標準入力の場合
は '<stdin>'
LINENO 処理中の行番号(1, 2, 3,…)
省略時のパターン
21
$ tse -s '' 'print(L)'
パターンが空文字列の場合、'.*' と同じ
$ tse -s '.*' 'print(L)'
省略時のアクション
22
$ tse -s '.*' ''
アクションが空文字列の場合、'print(L)' と同じ
$ tse -s '.*' 'print(L)'
beginアクションとendアクション
23
--begin オプション 起動直後に実行するアクション
--end オプション
ファイル読み込み終了後に
実行するアクション
$ tse --begin 's=0' 
--end 'print(s...
インポート済みモジュール
24
$ tse -s '.*' 'os.mkdir(L)'
sys, re, os, os.path はインポート不要
os.path は、from os import path 形式
$ tse -s '.*' '...
モジュールのインポート
25
--module/-m オプション
実行前にモジュールをインポートする
例) $tse -m math --begin 'print(math.sqrt(2))'
--module-star/-ms オプション
f...
エンコーディング指定
26
--input-encoding/-ie オプション
入力ファイルのエンコーディングを指定する
例) $tse -ie cp932 -s '' ''
--output-encoding/-oe オプション
出力ファイ...
--inplace オプション
27
入力ファイルを、出力で上書きする。
$tse --inplace .bak -s '' 'print(L.lower())' -- spam.txt
元のファイルは、指定した拡張子を付加した
ファイルに保存
--script-file/-f オプション
28
起動前に実行するスクリプトファイルを指定する。
$tse -f scr.py -s '' '' < spam.txt
デフォルトでは、~/.tserc ファイルが存在すれ
ば実行する。
拡張子ごとにファイルサイズ集計
29
$ find . -type f | 
tse -ms collections -b 'c=defaultdict(int)' 
-s '' 'c[path.splitext(L)[1]]+=path.ge...
ipアドレスからホスト名逆引き
30
$ cat log | tse -ms socket -s '' 
'try:print(gethostbyaddr(L1)[0], L1)' 
'except:print("unknown", L1)'
HTMLからa要素を抽出
31
$ curl www.python.jp | tse -ms 'bs4'
-b 'for a in BeautifulSoup(sys.stdin.read(),
"lxml").find_all("a"):{{...
ご清聴ありがとうございました
32
Upcoming SlideShare
Loading in...5
×

tse - Pythonによるテキスト整形ユーティリティ

687

Published on

PyCon JP 2015における、tse(https://pypi.python.org/pypi/tse) の解説

Published in: Career
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
687
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

tse - Pythonによるテキスト整形ユーティリティ

  1. 1. tse Text Stream Editor Pythonによる テキスト整形ユーティリティ 2015/10/10 PyCon JP 2015 Atsuo Ishimoto
  2. 2. 自己紹介 2 いしもと 石本 敦夫 あつお python.jp ドメインの管理者 @atsuoishimoto 著書 Pythonライブラリ厳選レシピ Python文法詳解 パーフェクトPython
  3. 3. Unixのテキスト処理といえば 3 sed, awk, perlなどのワンライナーが定番 Pythonでもワンライナーを書きたい 使い慣れたモジュール群を手軽に活用したい いちいちスクリプトファイルを作成したくない シェルのヒストリーから呼び出したい
  4. 4. Pythonはワンライナー向き? 4 向きません インデントと改行が必須 sys, reなどのimportなど、タイプ量が多い ワンライナー用のコマンドラインオプションがない  (Python2) Unicode(Encode|Decode)Error $ python -c 'print u"あ"'|less 等。。。
  5. 5. tse Text Stream Editor 5 Pythonによるテキスト整形ツール Pythonスクリプトをコマンドラインで指定 一般的なモジュール(sys, reなど)の自動イン ポート ファイルを読み込み、スクリプトを実行 入出力エンコーディングの指定
  6. 6. インストール方法 6 pip install tse Python2.7以降 Python3.3以降
  7. 7. tseの動作 7 1. テキストファイルを一行ずつ読み込み、 2. 行に一致するパターンがあれば、 3. 行を変数に代入し、 4.対応するアクションを実行する
  8. 8. $ tse -s '^d+' 'print(L.lower())' -s '^w+' 'print(L.upper())' パターンとアクション 8 パターン 入力行を検索する、正規表現式 アクション パターンの検索が成功した時に実 行するスクリプト パターン アクション-sオプションで指定
  9. 9. サンプル 9 'spam' を含む行を、小文字に変換して出力 tse -s "spam" "print(L.lower())" < s.txt
  10. 10. サンプル 10 行ごとに、すべての数字列の和を出力 tse -s ".*" "print(sum(int(s) for s in re.findall(r"d+", L)))"" < s.txt
  11. 11. パターン 11 例 • spam|ham 'spam' または 'ham' を含む行 • ^d+ 数字列で始まる行 reモジュールを利用 入力テキストを検索する正規表現式
  12. 12. アクション 12 例 • print('hello') 'hello'と出力 • print(L.upper()) 行を大文字に変換して出力 パターンがヒットした行で実行するスクリプト
  13. 13. 複数行のアクション 13 例 $tse -s '^w' 'if L:' ' print(L)' < spam.txt パターンには複数のアクションを指定できる。 2番目以降のアクションは、先頭のアクション の次の行として実行される。 if L: print(a)
  14. 14. インデント 14 $ tse -s '.*' 'if len(L)>5:{{print(1)}}' {{ と }} でインデントするブロックを指定する if len(L)>5: print(1) 文字列・コメント中の"{{}}" はインデントとして扱わない 例) 'print("{{spam}}{{ham}}")
  15. 15. 入力ファイルの指定 15 -s オプションに続けてファイル名を指定するとき は、オプションとファイル名を -- で区切る ファイル名が - のときは、標準入力から読み込む $tse -s '^d' 'print(S)' -- a.txt b.txt $tse -s '^d' 'print(L)' -- -
  16. 16. 変数 16 処理中のテキストは、変数に格納される 変数名 内容 L 現在処理中のテキスト行全体 L0 テキスト行を空白で区切った文字列の 配列 L1, L2,... テキスト行を空白で区切った文字列の 1番目、2番目、… N L0の長さ
  17. 17. マッチ文字列 17 正規表現にマッチした文字列も変数に格納 変数名 内容 S 正規表現にマッチしたグループの配列 S0 正規表現にマッチした部分文字列全体 S1, S2,... ()で囲んだグループの部分文字列 グループ名 '(?P<グループ名>)' で指定したグルー プの部分文字列 M ReモジュールのMatchオブジェクト
  18. 18. 変数のサンプル 18 $ echo 'ab cd ef'| tse -s '.*' 'print(L3, L2, L1)' ef cd ab 空白区切りの単語を出力 $ echo '123abc' | tse -s '(?P<num>d+)(.*)' 'print(num, S2)' 123 abc パターンの部分文字列
  19. 19. 変数のサンプル 19 $ls -l|tse -s '' 'if N>2 and int(L5)>=1024:print(L9)' サイズ>=1024のファイル名を出力 $ ls -l total 168 -rw-r--r-- 1 ishimoto staff 698 10 6 12:58 HISTORY -rw-r--r-- 1 ishimoto staff 1064 10 6 12:39 LICENSE -rw-r--r-- 1 ishimoto staff 35 10 6 12:39 MANIFEST.in 1 2 3 4 5 6 7 8 9
  20. 20. その他の変数 20 変数名 内容 FILENAME 処理中のファイル名。標準入力の場合 は '<stdin>' LINENO 処理中の行番号(1, 2, 3,…)
  21. 21. 省略時のパターン 21 $ tse -s '' 'print(L)' パターンが空文字列の場合、'.*' と同じ $ tse -s '.*' 'print(L)'
  22. 22. 省略時のアクション 22 $ tse -s '.*' '' アクションが空文字列の場合、'print(L)' と同じ $ tse -s '.*' 'print(L)'
  23. 23. beginアクションとendアクション 23 --begin オプション 起動直後に実行するアクション --end オプション ファイル読み込み終了後に 実行するアクション $ tse --begin 's=0' --end 'print(s)' -s '.*' 's+=len(L)' *.txt 例) *.txt ファイル全文字数を出力する
  24. 24. インポート済みモジュール 24 $ tse -s '.*' 'os.mkdir(L)' sys, re, os, os.path はインポート不要 os.path は、from os import path 形式 $ tse -s '.*' 'print(path.splitext(L)[1])'
  25. 25. モジュールのインポート 25 --module/-m オプション 実行前にモジュールをインポートする 例) $tse -m math --begin 'print(math.sqrt(2))' --module-star/-ms オプション from モジュール名 import * 形式でインポートする 例) $tse -ms math --begin 'print(sqrt(2))'
  26. 26. エンコーディング指定 26 --input-encoding/-ie オプション 入力ファイルのエンコーディングを指定する 例) $tse -ie cp932 -s '' '' --output-encoding/-oe オプション 出力ファイルのエンコーディングを指定する 例) $tse -ie cp932 -s '' ''
  27. 27. --inplace オプション 27 入力ファイルを、出力で上書きする。 $tse --inplace .bak -s '' 'print(L.lower())' -- spam.txt 元のファイルは、指定した拡張子を付加した ファイルに保存
  28. 28. --script-file/-f オプション 28 起動前に実行するスクリプトファイルを指定する。 $tse -f scr.py -s '' '' < spam.txt デフォルトでは、~/.tserc ファイルが存在すれ ば実行する。
  29. 29. 拡張子ごとにファイルサイズ集計 29 $ find . -type f | tse -ms collections -b 'c=defaultdict(int)' -s '' 'c[path.splitext(L)[1]]+=path.getsize(L)' -e 'for r in c.items():print(r)'
  30. 30. ipアドレスからホスト名逆引き 30 $ cat log | tse -ms socket -s '' 'try:print(gethostbyaddr(L1)[0], L1)' 'except:print("unknown", L1)'
  31. 31. HTMLからa要素を抽出 31 $ curl www.python.jp | tse -ms 'bs4' -b 'for a in BeautifulSoup(sys.stdin.read(), "lxml").find_all("a"):{{url=a.get("href", ""){{}}if url.startswith("http"):print(a["href"])'
  32. 32. ご清聴ありがとうございました 32
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×