Advertisement

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

Developer at BeProud Inc.
Oct. 10, 2015
Advertisement

More Related Content

Advertisement

Recently uploaded(20)

Advertisement

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

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