PDFを回転・保存するqpdfコマンド

MacOSのプレビューの不満
コマンド+Rで回転して保存しても変更が保存されない
非常に不便

そこでUNIXの出番
org.pdfを
時計回り(右回り)90度回転 +90
して、new.pdfをつくる

$ qpdf --rotate=+90 org.pdf new.pdf

これでOK

注意は、+90が数学における反時計周り・左回りではなく、その反対である点

qpdfはbrewでインストール

$ brew install qpdf
$ brew info qpdf
qpdf: stable 10.6.3 (bottled)
Tools for and transforming and inspecting PDF files
https://github.com/qpdf/qpdf
/usr/local/Cellar/qpdf/10.6.3 (81 files, 9.4MB) *
  Poured from bottle on 2022-03-14 at 22:21:47
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/qpdf.rb
License: Apache-2.0
==> Dependencies
Required: jpeg ✔, openssl@1.1 ✔
==> Analytics
install: 2,815 (30 days), 14,484 (90 days), 48,488 (365 days)
install-on-request: 2,148 (30 days), 10,922 (90 days), 33,609 (365 days)
build-error: 0 (30 days)

qpdfの詳細
https://qpdf.readthedocs.io/en/stable/cli.html?highlight=rotate#option-rotate

MacPro2009でTnsorflow+Kerasを使う

私のメインマシンはMacPro2009
拡張性の大きさから10年以上現役バリバリ
M1MacBook Proはサブ
他に
MacBook Pro Late 2013
MacBook Air Mid 2012
Dell OPTIPLEX 3020(Ubuntuメイン+NAS)
HP EliteBook 820(SSD分割Ubuntu+Win10)
東芝DynaBook T350(win7)
Macpc 001
これだけのマシンを駆使して
桜井進のPython・UNIX教室で使うUSBメモリーブートUbuntuシステムを作成できます
本当はテスト用に2016年〜2020年のMacBook Proが欲しい

さて本題
これらのマシンにPythonの実行環境がある
Pythonのバージョンメンテナンスで面倒なのがTensorFlow
それぞれのマシンで動くバージョンが違う(CPU、GPUの性能に異存)
Tensorflowのインストールだけでも手間がかかるのに
異存するライブラリのバージョンも関係するのでさらに面倒

なかでもメインマシンMacPro2009(10.15.6)はCPUが古いので
新しいTensorFlowは入らない
それでもTesorFlow 1.5.0なら動くことがわかった

ところが、
そこに画像認識をさせようとKerasを動かそうとするとこれが中々動いてくれない

試行錯誤の末、ようやくTnsorflow+Kerasが動く組合せを見つけた

Macにはpyenvを使ってPythonをインストール
これでPythonのバージョンを自在にコントロールできる
Python 3.6.5のインストール

$ pyenv install --list
$ pyenv install 3.6.5
$ pyenv global 3.6.5
$ pyenv rehash

同様にPython 3.6.6のインストールすると
次のように異なるバージョンのスイッチングが簡単にできて便利

$ pyenv versions
  system
* 3.6.5 (set by /Users/sakuraisusumu/.pyenv/version)
  3.6.6

TensorFlow 1.5.0 インストール

$ python -m pip install --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.5.0-py3-none-any.whl

組合せその1
Python 3.6.6
TensorFlow 1.5.0
keras 2.6.0(最新)

TensorFlow OK
Tnsorflow+Keras NG

組合せその2
Python 3.6.6
TensorFlow 1.5.0
keras 2.4.3(2.3.0、2.2.1)

TensorFlow OK
Tnsorflow+Keras NG

組合せその3
Python 3.6.5
TensorFlow 1.5.0
keras 2.2.1

TensorFlow OK
Tnsorflow+Keras OK

これでMacPro2009でもTnsorflow+Keraを使った画像認識ができるようになった
本当に微妙なバージョン違いです

$ python ai.py cat.jpg
Using TensorFlow backend.
2021-09-17 03:28:56.088497: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.2

keras+TensorFlowによる画像認識結果
                     確率
           tabby     71.12%
    Egyptian_cat     14.72%
       tiger_cat     10.62%
        radiator     0.55%
         doormat     0.27%

桜井進のPython・UNIX教室(入門コース全3回Zoom)の第3回授業風景
Dell OPTIPLEX 3020(Ubuntuメイン+NAS)でTnsorflow+Keraを使った画像認識を実行しているところ
スクリーンショット 66

MacOS UNIXコマンド locate

$ locate pytest

pipでpytestをインストールした際、whichとwhereisでpytestを探しても見つけられなかった
pipでアンインストールしようとしたら

$ python -m pip uninstall pytest
Found existing installation: pytest 6.2.4
Uninstalling pytest-6.2.4:
  Would remove:
    /Users/sakuraisusumu/.local/bin/py.test
    /Users/sakuraisusumu/.local/bin/pytest
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/_pytest/*
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/pytest-6.2.4.dist-info/*
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/pytest/*
Proceed (Y/n)? 

となり、/Users/sakuraisusumu/.local/bin/pytest にあることがわかった
これはこれで解決だが、
UNIXコマンドに検索があったはず(使ったことがなかった)と思いだし
findとlocateでpytestを探してみた

findは使い物にならない
locateはあらかじめデータベースを作っておくので全検索に近い
ところがだ
/Users/sakuraisusumu/.local/bin/pytest
が引っかからない
なぜだ?

locateを調べる

GNU版locateはfindutilsに入っているので

$ brew install findutils

によりインストールできる
glocateでpytestを検索するも変わらない

locateがデータベースをつくる歳にすべての領域を範囲とするわけでないことが判明
パーミッションが700である自分のディレクトリィの下は検索しない
そうだ

ということでHOMEにあるディレクトリでパーミッションが700のものを755に変更して
データベースをつくりなおしたところ今度は
/Users/sakuraisusumu/.local/bin/pytest
が見つかった

おかげでlocateについてだいぶわかった

MacOS Pythonにpytest インストール

$ python -m pip install pytest

インストールできたものの

$ pytest
zsh: command not found: pytest

あれれ?

$ which pytest
$ whereis pytest

だめだ、見つからない!
そこで一旦アンインストールすることに

$ python -m pip uninstall pytest
Found existing installation: pytest 6.2.4
Uninstalling pytest-6.2.4:
  Would remove:
    /Users/sakuraisusumu/.local/bin/py.test
    /Users/sakuraisusumu/.local/bin/pytest
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/_pytest/*
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/pytest-6.2.4.dist-info/*
    /Users/sakuraisusumu/.local/lib/python3.6/site-packages/pytest/*
Proceed (Y/n)? 

ここでようやくpytestの場所が判明
さっそく.zprofileにPATHを通してOK

dateで元号(令和平成昭和大正明治)表示

date → gdate

MacOS標準シェルzshのdateコマンドよりも
GNU系のdateコマンド(gdateコマンド)の方が気に入っている

$ which date
/bin/date
$ date
2021年 8月25日 水曜日 03時28分37秒 JST

このdateコマンドは次のようなGNU系dateコマンド(gdateコマンド)の作文ができない

$ date -d'10year 6month 3day 5hour 23minute 10second ago'

そこでgdateが使えるようにする

$ brew install coreutils

これによりglsやgdateのようなGNU版コマンドが100以上インストールされる
コマンドリストは次により確認できる

$ brew ls coreutils

ただgdateの標準出力が気にくわない

$ gdate
火  9  7 12:41:56 JST 2021

これはdateの出力のいいのでそれにあわせる
ついでに元号表示も工夫してみる

シェルスクリプト

.zprofile
に以下を追加

alias date="gdate +'%Y年%m月%d日%A%T'"
# 元号表示
function gendate()
{
y=(gdate +'%Y')
r=((y+1-2019))
h=((y+1-1989))
s=((y+1-1926))
t=((y+1-1912))
m=((y+1-1868))
n=(gdate +'%Y年%m月%d日%A%T')
echo '令和'r'年 平成'h'年 昭和's'年 大正't'年 明治'm'年 '$n
}

これで

$ date
2021年09月07日火曜日12:46:08

MacPro:~
$ date -d'10year 6month 3day 5hour 23minute 10second ago'
2032年03月10日水曜日18:09:05

MacPro:~
$ gendate
令和3年 平成33年 昭和96年 大正110年 明治154年 2021年09月07日火曜日12:46:19

これでOK

2段組PDFからテキスト抽出するコマンド

Mac標準でPDFからテキストを抜き出す簡単な方法はありません
Mac標準のAutomatorや専用アプリを使う必要があります
さらに二段組みPDFからテキスト抽出となると難しくなります

unixの「pdftotext」コマンドを使う方法なら1行でOK
二段組みのPDFにも対応します
hoge.pdf
から
hoge.txt
を生成するコマンドです

pdftotext -raw hoge.pdf - | sed ':loop; N; $!b loop; ;s/\n//g' >> hoge.txt
pdftotextのインストール

brewでpopplerをインストールすればOK

brew install poppler

次のコマンドがすべてインストールされる

pdftotext: converts PDF to text
pdftops: converts PDF to PostScript
pdftoppm: converts PDF pages to netpbm (PPM/PGM/PBM) image files
pdftopng: converts PDF pages to PNG image files
pdftohtml: converts PDF to HTML
pdfinfo: extracts PDF metadata
pdfimages: extracts raw images from PDF files
pdffonts: lists fonts used in PDF files
pdfdetach: extracts attached files from PDF files
pdfseparate: PDF to PNG/JPEG/TIFF/PDF/PS/EPS/SVG
pdfunite: PDF page merger

https://poppler.freedesktop.org/

pdfgray・pdfmin

pdfgray *.pdf → *.gray.pdf

スクリーンショット 71
MacOSのプレビューにはPDFグレイ変換オプションがある
ファイル→書き出す→グレイトーン
スクリーンショット 65
ところがやってみるとちゃんとグレイ変換されない
なぜか一部だけカラーのまま
これでは使い物にならない

そこでgsによるshellスクリプトの出番
以下のスクリプトを.zprofileに以下を追記するだけ
これでバッチリグレイPDFに変換できる

# pdfgray *.pdf
function pdfgray()
{
    local cnt=0
    for i in @; do
        gs -sDEVICE=pdfwrite \
           -sColorConversionStrategy=Gray \
           -dProcessColorModel=/DeviceGray \
           -dCompatibilityLevel=1.4 \
           -dNOPAUSE -dQUIET -dBATCH \
           -sOutputFile={i%%.*}.gray.pdf ${i} &
        (( (cnt += 1) % 4 == 0 )) && wait
    done
    wait && return 0
}

コンソール上で
pdfgray hoge.pdf
とすれば
hoge.gray.pdf
が出来上がる

$ pdfgray hoge.pdf
[3] 38381
[3]  + done       gs -sDEVICE=pdfwrite -sColorConversionStrategy=Gray  -dCompatibilityLevel=1.4
$ ls
hoge.pdf  hoge.gray.pdf
pdfmin *.pdf → *.min.pdf

おなじくプレビューのファイルサイズを減らすもイマイチ

.zprofile
に以下を追記

# pdfmin *.pdf
function pdfmin()
{
    local cnt=0
    for i in @; do
        gs -sDEVICE=pdfwrite \
           -dCompatibilityLevel=1.4 \
           -dPDFSETTINGS=/ebook \
           -dNOPAUSE -dQUIET -dBATCH \
           -sOutputFile={i%%.*}.min.pdf ${i} &
        (( (cnt += 1) % 4 == 0 )) && wait
    done
    wait && return 0
}

コンソール上で
pdfmin hoge.pdf
とすれば
hoge.min.pdf
が出来上がる

$ pdfmin hoge.pdf
[3] 38523
[3]  + done       gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE 
$ ls
hoge.pdf  hoge.min.pdf