Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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によるテキスト整形ユーティリティ

20,217 views

Published on

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

Published in: Career
  • Be the first to comment

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

×