HRR Co., Ltd.

技術的な記録を残していくことを目的としています。1次情報を大事にしています。

lsの実行結果をforでくるくる on Bash

はじめに

たまにBashスクリプトを書くときがあるのですが、毎回のように忘れるんですよね…。
例えば、配列の扱いやfor文の書き方など。

そこで今回は「lsの実行結果をforでくるくる」についてのメモを残すことにしました。

ソースコード

lsの実行結果を配列にして、forでくるくる

array=($(ls /home/${USER}/work))

for eachValue in ${array[@]}; do
    echo ${eachValue}
done

解説

コマンド実行について

`(バッククォート)で囲む方法もありますが、入れ子にできないのもあって私は$()を多用します。
その実行結果を()で囲むことにより、配列としています。

配列について

Bashの配列はこんなふうに()にスペース区切りになっています。

fruits=(apple orange banana)

lsコマンドを打つことで、自然とスペース区切りの文字列ができあがり、それを()で囲むことで配列としています。

for文と配列の展開

${array[@]}は配列の中身を展開するものです。

fruits=(apple orange banana)
echo ${fruits[@]}

# 出力:
# apple orange banana

なので、こんなふうに書いてもOK

for eachValue in apple orange banana; do
    echo ${eachValue}
done

# 出力:
# apple
# orange
# banana

${array[*]}っていうのもあるよね?

${array[*]}についても同じ、というような書き方をたまに見ますが、違いは明確にあります。
"(ダブルクォート)で囲まれたときに違いが出ます。

IFS=',|*'
fruits=(apple orange banana)
echo "${fruits[@]}"
echo "${fruits[*]}"

# 出力:
# apple orange banana
# apple,orange,banana

IFSの最初の1文字目が区切り文字として使われるんですね。
詳細はman bashをご参照ください。

最後に

Bashネタは今後も投稿すると思います。
今回は以上でした。

画像にある数字を抽出したい

はじめに

タイトル通りですが…そういうニーズが発生しました。
画像をいちいち目で確認していくのは、大変な労力がかかります…。

この手のことは、やはりPythonでやるものではないか?という先入観の元、調べていたのですが…。
TesseractというOCR (Optical Character Recognition/Reader、光学的文字認識) エンジンがあるとのことで、まずそれを試してみることに。
日本語で書くと「テッセラクト」ですかね。

環境はWindows7Cygwinを使用しております。

まずはインストール

こちらを参考にしております。
github.com

まずはapt-cygにて検索をかけます。

$ apt-cyg searchall tesseract
libtesseract-ocr_3
tesseract-ocr-deu
tesseract-ocr-devel
tesseract-ocr-eng
tesseract-ocr-fra
tesseract-ocr-ita
tesseract-ocr-nld
tesseract-ocr-por
tesseract-ocr-spa
tesseract-ocr-vie
tesseract-ocr
tesseract-training-core
tesseract-training-deu
tesseract-training-eng
tesseract-training-fra
tesseract-training-ita
tesseract-training-nld
tesseract-training-por
tesseract-training-spa
tesseract-training-util
tesseract-training-vie

すると出てきますね…ぞろぞろと。
メインどころであろう、下記パッケージをインストールしてみます。

$ apt-cyg install tesseract-ocr

すると長いログが出る出る…依存性のあるパッケージが次々とインストールされているようです。
整理してみると、こんな感じでした。
cygwinは抜いてます。
※一部再帰的になっていますが気にしない方向で。

tesseract-ocr
├ libgcc1
├ libleptonica_5
│ ├ libgif4
│ │ └ libX11_6
│ │    └ libxcb1
│ │       ├ libXau6
│ │       └ libXdmcp6
│ ├ libjpeg8
│ ├ libpng16
│ │ └ zlib0
│ ├ libtiff6
│ │ ├ libjbig2
│ │ ├ libjpeg8
│ │ ├ liblzma5
│ │ ├ libstdc++6
│ │ └ zlib0
│ ├ libwebp5
│ └ zlib0
├ libstdc++6
├ libtesseract-ocr_3
│ ├ libgcc1
│ ├ libleptonica_5
│ └ libstdc++6
└ tesseract-ocr-eng
   └ tesseract-ocr

これを見る感じ、画像形式はjpg, gif, png, tiffには対応できていそう。
言語パッケージはデフォルトは英語だけみたいですね。
バージョン情報を確認してみます。

$ tesseract --version
tesseract 3.04.01
 leptonica-1.73
  libgif 4.1.6(?) : libjpeg 8d (libjpeg-turbo 1.4.2) : libpng 1.6.24 : libtiff 4.0.6 : zlib 1.2.8 : libwebp 0.4.4

うん、入ってますね。

実際に使ってみる

というわけで、実際にお試しです。
適当にペイントソフトで作成した画像で、コマンドを叩いてみます。

f:id:hrroct:20170124170206p:plain

コマンドはWikiにもある通りです。

tesseract imagename outputbase [-l lang] [-psm pagesegmode] [configfile...]

・第一引数:画像
・第二引数:出力ファイル名
を最低限渡せばよさそうです。

$ tesseract NumberImage.png out
Tesseract Open Source OCR Engine v3.04.01 with Leptonica
Error in pixGenHalftoneMask: pix too small: w = 197, h = 76
$
$ cat out.txt
49612

読み取れてるー!!
エラーが出てきますが、画像の解像度(幅、高さ(px))が低い場合に出るようです。
github.com

まとめ

というわけで、あっさり画像認識ができました。
でも実際の写真に含まれる数字を抽出しようとすると…。

うまくいきません(´・ω・`)
(出力先のテキストが空っぽ…)
時間ができたら、もう少し戦ってみることにします。

Seleniumbasicで突如Google Chromeが開けなくなったら…

※2019/08/14:Windows 10の場合を追記しました

どうするか?

…ドライバを更新しましょう、という話です。

そもそもな話

Seleniumbasicとは何か?

florentbr.github.io

Seleniumはいろんな言語で使えるように横展開されています。
それのVB.NetVBAVBScript版になります。

経緯

久しぶりに Seleniumbasic でGoogle Chromeを開く処理を行ったんですが…

f:id:hrroct:20161208142719p:plain

というエラーが出ます。
はて。
プログラムは変えていないのに、なぜかエラーが出る。
IEなら問題なく開くのになぜ?

原因はドライバが古いこと、でした

Seleniumbasicのインストール先ディレクトリを見るとわかるのですが、「***driver.exe」というファイルがいくつかあります。
ブラウザはこれを使用して起動しているんですね。

私の場合はこちらでした。
「C:\Program Files\SeleniumBasic」(Windows 7)
「C:\Users\ユーザー名\AppData\Local\SeleniumBasic」(Windows 10)

Chromeのドライバもこちらにあるので、ダウンロードして置き換えましょう(以前のものはリネームする方がいいかも)。
「chromedriver.exe」という名前のファイルです。

取得先はこちら:

sites.google.com

更新すると…

元気にまた動いてくれました。
よかった…。

以上でした。

Chosenプラグインの使い方(基礎編2)

はじめに

Chosenプラグインネタ、第2弾です。
次は「発展編」とするはずが、複数選択時の場合が抜けていたので、それをまず書きます。

第1弾はこちら:
hrroct.hatenablog.com

第3弾も書きました:
hrroct.hatenablog.com

忘れていた、複数選択の場合

サンプルはこちら。
Edit fiddle - JSFiddle

jQuery 3.1.1
Chosen 1.6.2
を使用しております。

ベース

multiple属性とdata-placeholder属性が指定されているのが、単一選択時との違いです。

<select id="target" data-placeholder="Choose Some Items..." multiple>
    <option></option>
    <option value="1">1st Option</option>
    <option value="2">2nd Option</option>
    ...

選択された値を取得する

配列で取得するように揃えてみました。

// 配列で返ります
var valueList = $('#target').val();

// こちらも配列で取得してみる
var textList = [];
$('#target option:selected').each(function() {
    textList.push($(this).text());
});

値をセットする

セットする値を配列で与えればOKです。

// Chosenのバージョンが低い場合は'liszt:updated'で
$('#target').val([5,6]).trigger('chosen:updated');

値をクリアする

こちらも配列で指定します。空の配列ですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
$('#target').val([]).trigger('chosen:updated');

選択肢を追加する

これは単一選択時と変わらないですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
var newOption = $('<option>').attr('value', 15).text('15th Option');
$('#target').append(newOption).trigger('chosen:updated');

有効化、無効化

これも単一選択時と変わらないですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
// 無効化
$('#target').prop('disabled', true).trigger('chosen:updated');
// 有効化
$('#target').prop('disabled', false).trigger('chosen:updated');

以上でした!

Cygwinにapache2をインストール(2016年11月版)

はじめに

タイトルのとおりですが…
XAMPPではなく、Apache2をCygwinに入れて、http://localhost/でアクセスできるところまでやりました。
その手順を公開します。
※今回Windowsのサービスへの登録は行っていません!

手順

Apache2のインストール

まず、インストールから。
入れているapt-cygにより、コマンドは多少違いますが…
searchall or find すれば、見つかるはずなのでそれをinstallします。

$ apt-cyg searchall apache2
$ apt-cyg install apache2

ちなみに、各ファイルの場所はこんな感じです。

ファイルの種類 場所
exeファイル /usr/sbin/httpd.exe
設定ファイル /etc/httpd/conf/httpd.conf
デフォルトのDocumentRoot /srv/www/htdocs
デフォルトのエラーログ /var/log/httpd/error_log
デフォルトのアクセスログ /var/log/httpd/access_log

この時点でやっておくべき最低限の設定は、サーバー名の変更でしょうか。
localhostでアクセスできるようにしておきます。

#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
#ServerName www.example.com:80
ServerName localhost:80

Cygwinならでは、cygserverの起動

cygserverとは?

↓公式サイトに正確な情報が記載されています(英語)。
Cygserver

cygwin*.dll ではまかなえない機能を、Windowsの機能を用いて提供するプログラムらしいです。
apache2を起動するには、cygserverの機能が必要ということですね。
(浅い解説ですみません…時間の都合で先に進みます…)

cygserverデーモンを起動するには、まずは設定が必要になります。

設定ファイルを作成する

cygserver-configスクリプトを実行します。
パスが通ってない場合は "/usr/bin/cygserver-config" で。

また、途中で "Do you want to install cygserver as service?" と聞かれるので、今回は "no" で進めます。
(私の用途が、Windowsのサービスに登録するほどではないので)

$ cygserver-config
Generating /etc/cygserver.conf file

Warning: The following function requires administrator privileges!

Do you want to install cygserver as service?
(Say "no" if it's already installed as service) (yes/no) no

Further configuration options are available by editing the configuration
file /etc/cygserver.conf.  Please read the inline information in that
file carefully. The best option for the start is to just leave it alone.

Basic Cygserver configuration finished. Have fun!

"Have fun!" と言われたら、いざcygserverを起動してみましょう。

cygserverを起動する

バックグラウンドで起動します。

$ /usr/sbin/cygserver &
$ cygserver: Initialization complete.  Waiting for requests.

プロセスが立ち上がっているのを確認できたら、成功です。

$ ps | grep cygserver

Apacheの起動

下記コマンドを実行してみます。
エラーログ (/var/log/httpd/error_log) を "tail -f" しておくのをオススメします。

$ /usr/sbin/httpd -k start

私の場合は、下記エラーが表示されました。

AH01177: Failed to lookup provider 'shm' for 'slotmem': is mod_slotmem_shm loaded??
AH00020: Configuration Failed, exiting

"is mod_slotmem_shm loaded??" って言われたので、httpd.conf を編集します。
↓ここのコメントアウトを解除しました。

vi /etc/httpd/conf/httpd.conf
...
#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

そして、改めてApacheを起動してみると…
http://localhost/ に "It works!" が表示されました。
よかった…。

最後に

cygserverの存在は知らなかったので、いい勉強になりました。

Apacheのコマンドはヘルプを見るといろいろ載っています。
停止や再起動は↓こんな感じです。

$ /usr/sbin/httpd -h
 
$ /usr/sbin/httpd -k start
$ /usr/sbin/httpd -k stop
$ /usr/sbin/httpd -k restart

以上でした!