scpでリモートサーバからローカルにファイルを落とす&ローカルからリモートに転送する
↑ test-serverにあるfilesディレクトリの中身を、localに落としてきているところ。
scpコマンドについて
ファイルを送信したり、受信したりすることができる。
ファイル送受信時に使用するプロトコルはsshプロトコルなので安全。
また、使用帯域なども絞れるので、
他の通信を圧迫しないようにファイルの送受信をすることができる。
使用シーン
リモートホストの特定のディレクトリにある、大量のファイルを落としたい時。
ローカルで作ったシェルをリモートに置きたい時。
などなど。
使用法
リモートからローカルに落としてくる
scp [ユーザー名]@[ホスト名]:[リモートファイルパス] [ローカルファイルパス]
また、-r オプションを付けると、
ディレクトリ構造が保持されるので、便利。
scp -r [ユーザー名]@[ホスト名]:[リモートディレクトリパス] [ローカルディレクトリパス]
使用例
リモートホストにある、sshクライアントの設定ファイルを取ってくる時。
scp user@remote_host:~/.ssh/config ~/
ローカルからリモートに転送する
scp [ローカルファイルパス] [ユーザー名]@[ホスト名]:[リモートファイルパス]
ローカルファイルパスを複数指定すると、
複数個のファイルを取ってくることができるらしい。これも便利。
参考サイト
余談
なお、scpと語感が似ているsftpというコマンドがあるが、
結構違う。
イメージとしては、ftpのプロトコルがsshになった感じ。安全。
リモートにログインして操作ができるので、
リモート上でファイル名を変えたり、移動させたりすることができる。
canvasで画像を表示する
いきさつ
canvasを使って画像のリサイズをしたり、
画像のくり抜きがしたかったので、まずはcanvasで画像を表示できるようにした。
手順
1. input type='file'で画像を登録できるようにする
<input type="file" id='file'>
2. fileを登録した時にイベントが発火するようにする
/** input要素の取得 */ const input = document.getElementById('file'); /** inputに画像を追加した時にイベントを受け取る */ input.addEventListener('change', function(e) { /** 処理 */ }
3. 処理を書く
/** inputに画像を追加した時にイベントを受け取る */ input.addEventListener('change', function(e) { /** File オブジェクトを読み込む */ const file = e.currentTarget.files[0]; const fr = new FileReader(); fr.onload = function() { /** ファイルが読み込まれたあとの処理 */ const image = new Image(); /** 画像がimageタグに読み込まれた後の処理 */ image.onload = function() { ctx.beginPath() ; ctx.drawImage(this, 50, 0, 400, 400, 0, 0, 200, 200); } image.src = fr.result; } fr.readAsDataURL(file); });
解説1
canvasで画像を描く際、drawImageというメソッドを用います。
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
imageはHTMLImageElement, HTMLCanvasElement, HTMLVideoElement のいずれかを取ることができます。
ということは、まずはHTMLImageElemenetを生成する必要があります。
解説2
const image = new Image();
でHTMLImageElemenetが生成できます。が、
Imageのsrcを指定する必要があります。
const image = new Image(); /** 画像がimageタグに読み込まれた後の処理 */ image.onload = function() { ctx.beginPath() ; ctx.drawImage(this, 50, 0, 400, 400, 0, 0, 200, 200); } image.src = fr.result;
こんな感じで。
fr.resultはFileReaderがFileオブジェクトを読み込んだ際の結果です。
ソースコード
macのlocal環境にtypescriptを導入
職場が静的型付け言語使ってきた人が多いので、
その人達の学習コストの事だったり
コンパイル時にバグを発見できたりであったり
そんな事情でtypescriptを使っています。
導入の仕方の備忘録。
typescriptの導入
1. typescriptをglobal install
npm install -g typescript
2 . コードを書く
class Dog { private name: string; constructor(name: string) { this.name = name; } } const dog = new Dog('pochi');
3. typescriptからJavaScriptにコンパイルする
tsc hello.ts
こんなjsファイルが生成されます。
var Dog = /** @class */ (function () { function Dog(name) { this.name = name; } return Dog; }()); var dog = new Dog('pochi');
webpackの導入
いちいちコンパイルするの面倒くさいよね。
ファイル保存時に自動でコンパイルしてくれたらうれしい
コンパイルが終わった後にいちいちブラウザリロードするの、 面倒くさいよね。
コンパイルが終わったら自動でブラウザをリロードしてくれるとうれしい
コード量が増えたらファイル分けたいよね。
外部ファイルが読み込めるようになったらうれしい
webpackを導入しましょう。
(次回の記事)
地下アイドル「私、ぜったい売れっ子アイドルになるんだから!」で学ぶデザインパターン(Observer)〜アイドルとオタクを疎結合にしてみた〜
ある日の地下アイドル
地ア「は〜あ。今日もライブは3人しかこなかったなぁ」
地ア「きょう来てくれたのは、たっくんと、しのぶんと、ゆっきーか」
地ア「この3人、いつも来てくれるんだよねぇ。大事にしなくちゃ」
地ア「私、ぜったいに売れっ子アイドルになるんだから!」
地ア「…そろそろCD発売だから、告知しよっと」
アイドルクラス
/** アイドルクラス */ function ChikaIdle() { } ChikaIdle.prototype.noticeCdRelease = function() { /** わたし、みんなの名前も顔も覚えてるよ! */ var takkun = new Otaku('takkun'); var shinobun = new Otaku('shinobun'); var yukki = new Otaku('yukki'); /** CD買って(はあと) */ console.log('みんなだいすき!CD買ってね!'); takkun.getCd(); shinobun.getCd(); yukki.getCd(); }
アイドルによる告知
var chikaIdle = new ChikaIdle(); chikaIdle.noticeCdRelease();
オタククラス
/** オタククラス */ function Otaku(name) { this.name = name; } Otaku.prototype.getCd = function() { console.log(this.name + 'はCDをぜってーかうぜ!!'); }
告知結果
みんなだいすき!CD買ってね! takkunはCDをぜってーかうぜ!! shinobunはCDをぜってーかうぜ!! yukkiはCDをぜってーかうぜ!!
だんだん売れてきた地下アイドル
地ア「今日は10人もライブに来てくれた!!」
地ア「きょう来てくれたのは、たっくんと、しのぶんと、ゆっきーと、ちーくんと、るなくんと、、、」
地ア「ほげくんとほげくんとほげくんかぁ」
地ア「そろそろCD発売だから、また告知しよっと」
アイドルクラス
/** アイドルクラス */ function ChikaIdle() { } ChikaIdle.prototype.noticeCdRelease = function() { /** わたし、みんなの名前も顔も覚えてるよ! */ var takkun = new Otaku('takkun'); var shinobun = new Otaku('shinobun'); var yukki = new Otaku('yukki'); var chi = new Otaku('chi'); var luna = new Otaku('luna'); var hoge1 = new Otaku('hoge1'); var hoge2 = new Otaku('hoge2'); var hoge3 = new Otaku('hoge3'); var hoge4 = new Otaku('hoge4'); var hoge5 = new Otaku('hoge5'); console.log('みんなだいすき!CD買ってね!'); /** CD買って(はあと) */ takkun.getCd(); shinobun.getCd(); yukki.getCd(); chi.getCd(); luna.getCd(); hoge1.getCd(); hoge2.getCd(); hoge3.getCd(); hoge4.getCd(); hoge5.getCd(); }
アイドルによる告知
var chikaIdle = new ChikaIdle(); chikaIdle.noticeCdRelease();
メッチャ売れてきたアイドル
地ア「すごい!今日ははじめて箱(ライブハウスのこと)がいっぱいになったよ!」
地ア「200人も来てくれた!」
地ア「今日来てくれたのはたっくんと、しのぶんと、ゆっきーと、ちーくんと、るなくんと、、、」
地ア「アアアアアアアアアアアアアアアアアアアアアア!!!!!!!」
しのぶん「地下アイドルちゃん!僕の事今日から、しのぶーって読んでね!」
/** アイドルクラス */ function ChikaIdle() { } ChikaIdle.prototype.noticeCdRelease = function() { /** わたし、みんなの名前も顔も覚えてるよ! */ // var shinobun = new Otaku('shinobun'); var shinobu = new Otaku('shinobu'); // shinobun.getCd(); shinobu.getCd(); }
地ア「ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛!!!!!!!」
どうしてこうなったのか
地下アイドルがいろいろ知りすぎです。
このままでは、
オタク達が増えるたびに地下アイドルクラスに変更が行われ、
オタク達のあだ名が変わるたびにまた、地下アイドルクラスに変更が行われます。
つまり、
地下アイドルクラスはめちゃくちゃ仕様変更に弱いクラスということになります。
その時、地下アイドルは気づいた
地ア「そうだ!」
地ア「私は別に、みんなの名前を覚えなくていいんだ!」
これがObserverパターンの始まりです(嘘)
Observerパターンで書き直す
アイドルクラス
/** アイドルクラス */ function ChikaIdle() { this.fans = []; } ChikaIdle.prototype.addFan = function(fan) { this.fans.push(fan); } ChikaIdle.prototype.noticeCdRelease = function() { console.log('みんなだいすき!CD買ってね!'); /* * アイドルはファンの名前は誰も知らない。 * 知っているのはCDを買ってくれるということだけ */ this.fans.forEach(function(fan, index, fans) { fan.getCd(); }); }
アイドルクラスから、
Otakuクラス、
Otakuの名前が全て消えました。
アイドルが知っているのは、
fanが「getCd」というメソッドを持っていることだけです。
もう、アイドルはオタクの顔も名前も思い出せません。
知っているのは、「告知をしたら、CDを買ってくれる」というただ1つだけ。。。
アイドルとオタクが非常に疎結合な、良い設計になりました。
使い方
var chikaIdle = new ChikaIdle(); var takkun = new Otaku('takkun'); var shinobun = new Otaku('shinobun'); var yukki = new Otaku('yukki'); var chi = new Otaku('chi'); var luna = new Otaku('luna'); var hoge1 = new Otaku('hoge1'); var hoge2 = new Otaku('hoge2'); var hoge3 = new Otaku('hoge3'); var hoge4 = new Otaku('hoge4'); var hoge5 = new Otaku('hoge5'); chikaIdle.addFan(takkun); chikaIdle.addFan(shinobun); chikaIdle.addFan(yukki); chikaIdle.addFan(chi); chikaIdle.addFan(luna); chikaIdle.addFan(hoge1); chikaIdle.addFan(hoge2); chikaIdle.addFan(hoge3); chikaIdle.addFan(hoge4); chikaIdle.addFan(hoge5); chikaIdle.noticeCdRelease();
さらなるメリット
アイドルは、CDを買ってくれる人ならだれでも通知することが出来ます。
/** 一般ピーポークラス */ function IppanPeople(name) { this.name = name; } IppanPeople.prototype.getCd = function() { console.log(this.name + 'はちょっと興味があるからCDかうよ'); }
getCdメソッドを持つクラスをまとめて扱うことが出来ます。
疎結合にしたことにより、ポリモーフィズムも使えるようになりました。
まとめ1
Observerパターンは、通知する側とされる側を疎結合にする。
まとめ2
アイドルとオタクを疎結合にすると、
アイドルはオタクの顔も名前も覚えなくなり、
知っているのは「告知をしたら、CDを買ってくれる」というただ1つだけという
夢も希望もなくなる感じになる。
【JavaScript】画像をdrag and dropしてサムネイルを表示する〜DragEvent, DataTransfer, File, FileReaderオブジェクトについて〜
こういうのがやりたかった
手順
簡単に言うと、
DragEventからDataTransferを取得
DataTransferからFileを取得
FileをFileReaderで読み込み、サムネイルとして表示
という手順になります。
1. dropエリアの準備
1-1. まずはdropエリアを作成する
imgは後でサムネイルを表示する際に使います。
<div id='droparea'> </div> <img src='' id='thumb'>
#droparea { width: 200px; height: 100px; border: 3px dotted #ccc; }
1-2. dropエリアにイベントリスナを登録
const droparea = document.getElementById('droparea'); droparea.addEventListener('drop', function(evt) { console.log('dropしたよ'); /** 以下、drop後の処理 */ }, true);
この中にdrop後の処理を書き込んでいきます。
2. dragしたファイル(Fileオブジェクト)を受け取る
dropしたファイルを取得します。
まず、dropイベントの中身を見てみましょう。
console.log(evt);
DragEventというオブジェクトのようです。
今回用があるのは、このオブジェクトが持つ
DataTransferというオブジェクトです。
console.log(evt.dataTransfer);
DataTransferオブジェクトがもつfilesというプロパティから、
ドラッグされたFileオブジェクトにアクセスすることが出来ます。
/** 全件取得 */ console.log(evt.dataTransfer.files); /** 1件取得 */ console.log(evt.dataTransfer.files[0]);
複数件まとめて扱うこともできそうですね。
3. 取得したFileオブジェクトを、FileReaderで読み込む
ソースコード
droparea.addEventListener('drop', function(evt) { // ファイルオブジェクトの取得 const file = evt.dataTransfer.files[0]; // FileReaderの生成 const reader = new FileReader(); reader.onload = function() { // ファイルを読み込んだ後の処理 console.log(reader.result); // サムネイルとして表示 const thumb = document.getElementById('thumb'); thumb.src = reader.result; }; // ファイルの読み込み reader.readAsDataURL(file); // ブラウザのデフォルト挙動を抑制 evt.preventDefault(); }, true);
FileReaderの解説
html5から、
FileReaderというローカルファイルを読み込めるAPIが使えるようになりました。
FileReaderが扱えるのはFileオブジェクト(またはBlobオブジェクト)です。
reader.onload = function() { // ファイルを読み込んだ後の処理 // reader.resultでファイル内容にアクセスできる };
としてファイルを読み込んだ後の処理を記載します。
読み込んだ結果は、
reader.resultでアクセスできます。
reader.readAsDataURL(file);
としてファイルオブジェクトを読み込みます。
完成したソースコード
const droparea = document.getElementById('droparea'); // dropイベントのリスナーを設定 droparea.addEventListener('drop', function(evt) { // Fileオブジェクトの取得 const file = evt.dataTransfer.files[0]; // FileReader生成 const reader = new FileReader(); // ファイルを読み込んだ後の処理 reader.onload = function() { // サムネイルとして表示 const thumb = document.getElementById('thumb'); thumb.src = reader.result; }; // ファイルの読み込み reader.readAsDataURL(file); evt.preventDefault(); }, true);
bashで特定の文字列を含むファイルの名前を、一括置換する
bashである文字列を含むファイルについて、一括置換したかった
カレントディレクトリにあるファイルのうち、
無題を含むものをmudaiに変える、みたいなことがしたかった。
結論
解説
まず、以下のようにファイルを準備します。
$ touch hogeA hogeB fugaC
これらのファイルのうち、以下の2つのファイル名を
hogeA -> ho:)geA hogeB -> ho:)geB
と変更することにします。
for文
こう書けば、カレントディレクトリのファイルについて
ループ処理をすることが出来ます。
# run.sh for file in * do echo ${file} done
$ sh run.sh fugaC hogeA hogeB
sed
新しいファイル名を生成する際、正規表現を使うことがあります。
そのときはこのsedを使いましょう。
以下のように使うことが出来ます。
$ echo hogeA | sed -E 's/(ho)(ge)/\1:)\2/g' ho:)geA
-E オプション
正規表現が使えます。
's/(ho)(ge)/\1:)\2/g' について
ho, geという文字をかっこでくくることにより、キャプチャを撮っています。
そして、\1, \2で再度アクセスしてます。
\1, \2の間にhappy simbolをいれてます。
mv
forとsedを組み合わせて、
sedで新しいファイル名を生成しつつ、
mvでその新しいファイル名に変更していきます。
for file in * do after_file=`echo ${file} | sed -E 's/(ho)(ge)/\1:)\2/g'` mv -i "${file}" "${after_file}" done
まとめ
sedコマンド、とても便利。
とくにキャプチャを取り始めるとその便利さに驚く。
今回、xargsなどを用いるともっと簡単にかけるかもしれないが、
可読性のためにココらへんでとどめておくことにした。
またチャレンジしたい。
bashは最強のポータビリティ言語。
MySQLにて、特定のカラムに日本語が含まれているかどうかを抽出
あるカラムに日本語が含まれていることを検出したい
結論
あるカラムに対して、
LENGTH
CHARACTER_LENGTH
の値が異なることを利用する。
SQLの例
SELECT * FROM table_name WHERE LENGTH(column_name) != CHARACTER_LENGTH(column_name);
解説
LENGTHは「バイト」数
CHAR_LENGTHは「文字」数
なるほどねぇ。