Bag of ML Words

ML = Machine Learning, Music Love, and Miscellaneous things in daily Livings

Linux便利コマンドの覚書

コマンドラインでいろいろ文字列処理できるよっていうね。

常にpythonperlさん使うより、覚えていたらずっと早かったりする。

そこで、便利だったコマンドを、実際の自分のusageに即してメモする。

というか100本ノックの第二章やってるだけです

 

www.cl.ecei.tohoku.ac.jp

 

cut

デフォルトでは、タブ区切りファイルからコラムを切り出せる。

tsvファイルがあったときに、その第1, 3コラムだけを抽出するには

cat hoge.tsv -f1,3 

結果がほしいときは

cat hoge.tsv -f 1, 3 > output.tsv

とする。

 

区切り文字を変える時には-dをつける

cat hoge.csv -d',' -f2

など

 

sed

文字列変換。

sed -e 's/ABC/DEF/g' hoge.txt > replaced.txt

で、hoge.txt内の"ABC"がすべて"DEF"に置換されてreplaced.txtに出てくる

 

paste

二つのファイルを、同じファイル行数ごとに連結する。

これ、実はすごく強力ではないか?入力ストリームを2つ同時に進めるってのは普通のプログラムだと難しいような気が(少なくとも perlの <>だけではできない?)

paste file1.txt file2.txt > file12.txt #concat with tab (default)

paste -d":" file1.txt fil2.txt > file12-colon.txt # concat with colon. -d to specify the connecting character

paste -d"ABC" fileq.txt file2.txt > file12-A,txt # どうも文字列の最初の1文字しか使わないようだ。この場合は"A"で連結される

 

 sort

入力されたファイルを、ソートして並べ替える。

これまた神コマンドかもしれない。

例えば

高知県 江川崎 41 2013-08-12
埼玉県 熊谷 40.9 2007-08-16
岐阜県 多治見 40.9 2007-08-16
山形県 山形 40.8 1933-07-25
山梨県 甲府 40.7 2013-08-10

みたいな(タブ区切り)データがあったとき

sort -n -k3 data.txt # 第3列 (-k3)を、数値として(-n)、昇順にソート

大阪府 豊中 39.9 1994-08-08
岐阜県 美濃 40 2007-08-16
群馬県 前橋 40 2001-07-24
山形県 酒田 40.1 1978-08-03

sort -n -k3 -r data.txt # -rで降順になる

山形県 酒田 40.1 1978-08-03
群馬県 前橋 40 2001-07-24
岐阜県 美濃 40 2007-08-16
大阪府 豊中 39.9 1994-08-08

 これは圧倒的便利

 

cat

cat自体はまあ普通だけど、頭のよい使い方を

cat コマンド | コマンドの使い方(Linux) | hydroculのメモ

で見かけたので下記に引用する。

 

行数が膨大なテキストファイルに対してなにかの処理をしたい。

処理に時間がかかってしまうが、その “なにか” を処理させるワンライナーが正しいかどうか不安で何度か試行錯誤する必要がある場合に、試行錯誤中は、テキストファイル全体を処理するのではなく、headでファイルの一部だけを処理してみる。

ワンライナーが完成したときに、コマンド履歴の headcat に書き換えるだけで処理を完成させることができる。

“なにか” が仮に文字コード変換だとすると、こんな感じ。

## テキストファイルの文字コードがわからないが、とにかくUTF-8にしたい
$ head huge.txt | nkf --guess
CP932 (CRLF)

## CP932 というのをUTF-8にするにはどうしたらいいんだっけ?
$ head huge.txt | nkf -sW
...

## 違った、文字化けしちまった、こっちかな?
$ head huge.txt | nkf -Sw
...

## 合ってた。さて、改行コードはどうなってる?
$ head huge.txt | nkf -Sw | nkf --guess
UTF-8 (CRLF)

## 改行コードも直したい
$ head huge.txt | nkf -Sw -Lu | nkf --guess
UTF-8 (LF)

## OK。じゃあ、本番
$ cat huge.txt | nkf -Sw -Lu > result.txt

最後の本番のコマンドは nkf -Sw -Lu huge.txt > result.txt でもよいのだが、直前のコマンド履歴のheadcat に書き換えるだけのほうが、タイピングが楽で間違えないのである。このとき cat はほとんど意味のある仕事をしないが、タイピングを楽にすることに意味がある。

 

 

screenの使い方!

実に10年ぶりくらいぶりにマシンをつけっぱなしにできない状況になったので、改めてscreenを再勉強。

 

screenの特徴は、一つのターミナル画面上で番号の切り替えで多数のセッションを作ることだけど、もう一つの特徴として「セッションはバックグラウンドで走っているのでそのターミナルを殺しても生き残る」というのがある。

 

ので、手元のマシンからsshで計算サーバにログイン、計算を回すという状態のときに

i) 計算サーバでscreenして新しい仮想ターミナルを作成、ログイン

ii ) 計算ジョブを投げる

iii) screenしたターミナルから抜ける

と、あとはsshが切れても計算サーバ上では ii) のジョブが生き残ってくれる。

で、後日改めて計算サーバ上でscreenしていたターミナルにログインすれば計算結果が回収できるというわけ。

 

portforwarding + autossh + sshfsと合わせて利用するので、ここで必要なコマンドを備忘録的にメモ。

 

新しいスクリーンを始める: 

screen

スクリーンから離れる: detach from screen(殺さないで親ターミナルにもどる)

Ctrl-a d

入れ子でスクリーンするとわかりにくいので、新しくスクリーン作るときはいちいちスクリーンから離れて、親ターミナルに戻ったほうが良さげ。

 

今あるスクリーンを調べる: list screens

screen -ls

スクリーンのIDが並びます

 

指定のスクリーンに戻る: resume screen 

screen -r ID

 

スクリーンを殺す

exit

ただのターミナルなのでね

ansible導入テスト(Docker, Jenkinsへの道 on Windows(3))

続いて、構成管理ツール(?)であるansibleを試す。

 

ansibleのほうがchefよりも後発でネガをつぶしているのと簡単構成向きらしい。

 

 

試す

qiita.com

これにならって、サーバ二つ構成の最小セットアップをvagrant + virtual box上に構成、そこで片方のサーバでもう片方をansibleで管理するテストを行う。

 

作った環境ではcentos6.5なので、Vagrantfileはちょっとだけ変わる。

Vagrant.configure(2) do |config|
  config.vm.define "controller" do |node|
    config.vm.box = "centos65"
    config.vm.hostname = "controller"
    config.vm.network "forwarded_port", id: "ssh", guest: 22, host: 2210
    config.vm.network "private_network", ip: "192.168.100.10"
  end
  config.vm.define "target" do |node|
    config.vm.box = "centos65"
    config.vm.hostname = "target"
    config.vm.network "forwarded_port", id: "ssh", guest: 22, host: 2220
    config.vm.network "private_network", ip: "192.168.100.20"
  end
end
 

 vagrant upで長らく待つとちゃんとcontrollerもtargetも起動する。

 

こけた

ちょっと何かupdateしてしまったら、ビルドが壊れた・・・

kernel-develのversion有ってないよってなる。

そのときは

qiita.com

を参照して下さい。

 

無事起動したらansibleインストール

f:id:Dr_KayAi:20160527235022p:plain

よしよし。ということでcontrollerサーバにsshして、ansibleをyum installする。

f:id:Dr_KayAi:20160527235327p:plain

あれ、なんかtargetになってるが、まあいいや。

targetからcontrollerを支配しよう・・・・

f:id:Dr_KayAi:20160528001050p:plain

つながったポイ??

 

 

「オブジェクト指向と10年戦ってわかったこと」が素晴らしかった

qiita.com

これです。

 

自分はJava使い*1なのですが、オブジェクト指向の価値を全然活かせていないなぁと常々思っていました。

色々原因がありそうですが、この記事にあるようにしっかり考えてないからだ、ということがわかりました。

 

幾つか、自分に刺さったところを自分のために引用しておきます。

気になった人はリンク先の本文をぜひ読んでください。

 

クラスはとっかえひっかえするものをクラスにする

オブジェクト指向で書く理由、それは変更に対して柔軟に対応するためです。

(省略)

オブジェクト指向によるアプリケーション開発は、変更されない箇所を軸に、頻繁に変更される箇所をクラスに抽出するプログラミングスタイルです。

 

 

継承は様々な具体的なクラスを抽象化するためのボトムアッププロセスで、トップダウンにすべきではない

継承は機能を受け継ぐためのものではありません。継承の本質は、犬や猫を「動物」という抽象概念としてまとめ上げられるインターフェイスなのです。 

 

その証拠として、別のクラスの機能を利用する方法にコンポジションがあります。コンポジションを使えば人間がパーツを組み合わせて「車」を作るような自然なオブジェクトの作り方ができるし、実は継承よりコンポジションの方がよく使います。

 

ポリモーフィズムは抽象のスーパークラスを扱う(ことによって見通しを良くする)

継承の本質はインターフェイスであると説明しましたが、ポリモーフィズムはそのインターフェイス(抽象)に対してプログラムするということです。 

 

インスタンスをnewするのはメインクラス。メインクラスは素材を出して処理する調理場。

そのため、ファクトリを作るまでもないインスタンス生成はメインクラスで行うようにしましょう。メインクラスでnewしたインスタンスを他のクラスに渡すのです!

(省略)

メインクラスは調理場のような存在であり、メインクラスに疎結合性やモジュール性は必要ありません。そのため、メインクラスがnewの接着剤でベトベトに汚れてしまっても何も困ることはないのです。

 

カプセル化は難しい

しかし、小刻みにブレーキを踏まなければスリップし、小まめにギアチェンジする必要があり、カーブするときは倒れないように体重移動をしなければ倒れてしまう自動車があったら、僕はそれを運転できません。複雑だからです。だけど、ブレーキにはABSを搭載し、ギアはオートマチックで、カーブするときは倒れないよう重心が設計されていれば、あれこれ考えず運転できます。

つまりカプセル化とは複雑な部分を隠し、無駄な操作をしなくても良い状態にそのものを洗練させ、分かりやすい状態にするということです。

(省略)

実はこの「無駄を省き洗練させてわかりやすくする」というのはオブジェクト指向の原則というより、より抽象度の高い「デザイン」の原則なのです。

オブジェクト指向に不可欠なのはカプセル化ですから、つまり、オブジェクト指向でプログラミングする人にはデザインのセンスが必要になるということになります。

そんなもの、難しくて当然です!

 

 カプセルにはただしい名前が必要

自動車には「自動車」という名前が、エレベーターには「エレベーター」という名前が付けられています。もしあなたが何かをカプセル化した場合、そのものにまだ名前が付いていない時は、それに正しい名前をつけるということが、カプセル化の最後の仕上げになります 

 

*1:そしてC++使いになりたいわなびー

Ubuntu-based Docker imageでDocker初体験(Docker, Jenkinsへの道 on Windows(2))

最初はvagarnt上のcentosで改めてvirtual box, vagrant, そしてdockerと思っていたのですが・・・

 

こけたので、バイパスルート。

とりあえずvirtual vox + vagrantができたのでcoreosを落としてきます。

それには初めからdockerあるらしいので!(あるだけだと思うけど)

 

qiita.com

 

これに完全にならうだけ(何の工夫もしない)・・・できた。DockerでUbuntuhello worldってechoした!

(本当にそれだけ。使い方もわかってない)

Vagrantで仮想マシンぽこぽこ(Docker, Jenkinsへの道 on Windows(1))

ちょっとアレでアレなので、DockerとかJenkinsとかいう流行りものを触るだけでも触っておきたい*1という動機が出てきました。

 

で、いろいろ調べると、こういうものは仮想開発環境による開発/テスト/サービスデプロイ環境の環境同定・構築のために使うのが基本らしいということがおぼろげながらわかってきました。*2

なのでもう1からやってみようということで、まずはVagrantによる仮想マシン環境のセットアップから。

 参考にするのは

Vagrant始めました — | サイオスOSS | サイオステクノロジー

Windows上でVirtualBox+Vagrant+CentOSによる仮想環境構築 - Qiita

です。

Vagrantとは

仮想マシンソフトを簡単に使うためのフロントエンドとなるツール、らしい。

特に仮想環境をたくさん使ったりあるいは頻繁に変えるようなお仕事状況ではいちいちVMware/VirtualBoxでぽちぽちインストールとかしてらんないので、

仮想マシン+仮想OS環境の設定ファイルとイメージをコマンド一つで呼んで仮想環境を起動・破棄できるようにする

のがメインのご利益ぽい。

 

まずは仮想マシンソフトのインストール

ここではVagrantのデフォルトらしい、OracleVirtualBox. VMwareだと面倒っぽいので。

Oracle VM VirtualBox

 

ここからWindows 64bit用のインストーラをダウンロードしてインストールです。

何も考えることなくインストール完了。

 

Vagrantのインストール

Vagrantも公式HPからダウンロードしてインストールします。

Vagrant by HashiCorp

Linux(Ubuntu)だとyumでいけるっぽい・・・?

 

今回はwindowsなのでインストーラ持ってきてインストール。

cmd.exeでvagrantのバージョンが出ればひとまず成功。

 

OSのイメージをゲット(Vagarnt box)

VagarantのOSその他設定ファイルイメージであるところの"box"をダウンロード。これを読み込んであげれば仮想環境(VirtualBox)上でLinuxが立ち上がるって寸法だな?

今回はCentOS6.5を選択。

f:id:Dr_KayAi:20160430011702p:plain

 

cmd.exeでgithubからダウンロード。

$ vagrant box add centos65 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box

よしよし。

f:id:Dr_KayAi:20160430012321p:plain

$vagrant box list

centos65 (virtualbox, 0)

でcentos65ができていればOK.

 

いよいよ仮想OS起動!

まずは作業ディレクトリを作って初期化。

$ mkdir centos

$ cd centos

$ vagrat init centos65

f:id:Dr_KayAi:20160430013026p:plain

 

 Vagrantファイルができたので初期修正が必要だよ。GUIを入れましょう。

f:id:Dr_KayAi:20160430013556p:plain

 

さあ、upすればCentOSが来るよ

$vagrant up

 

f:id:Dr_KayAi:20160430013958p:plain

 

キターーーーー!

 

あとは好きなbox取ってくれば同じ要領でいくらでも仮想環境を作れますね!

 

最後に

vagrant、以下のプラグインは入れておいたほうがよさそうです

vagrant-winnfsd

vagrant-vbguest

vagrant-proxyconf

 

 

 

 

*1:あーあれね、触ったことありますよ(キリッ というのがしたい

*2:ということはあれか、家での宿題とか勉強のためのプログラミング練習とかでは単にWindows + VMware + Ubuntuで十分ってことか?