カテゴリー別アーカイブ: Tips

Windowsのコマンド・プロンプトの拡張子の取り扱い

[NT] コマンド プロンプトでの拡張子の取り扱い http://support.microsoft.com/kb/164351/ja

コマンド プロンプトからワイルドカードを使ってファイル管理を行う場合、3 文字を超える長い拡張子は、3 文字に切り詰められて取り扱われます。 というわけで、上のリンクのガイドに従って、レジストリエディタで HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem Win95TruncatedExtensions : REG_DWORD を 0 へ変更(デフォルトは 1)して、再起動 ところが、もう一度試してみても、やっぱり3 文字に切り詰められて取り扱われるのか、以下のようなコマンドを実行すると、ひっかかって欲しくない拡張子4文字以上のファイルもヒットしてしまう。

> dir /B *.htm
index.htm
index.html

このレジストリ値を変える以前に作ったファイルには効かないようだ。レジストリ変更後に作った拡張子4文字以降のファイルはちゃんとその通り扱われていた。 うっかり削除なんて事故も起きかねない。コマンド・プロンプトでワイルドカードを使うときは十分注意が必要だね。

Google +1ボタンをWordPressに設置する

Google +1 ボタンをWordpressに設置する方法。
+1ボタンとは、字の通りイチオシといったところかな。


Google +1
  Add +1 to your pages to help your site stand out


上のリンク先に行って、SizeとLanguageを選ぶと埋め込みコードができるよ。

SizeをMedium(20px)、LanguageをJapaneseにした場合は次のようなコードができあがる。

<!-- Place this tag in your head or just before your close body tag -->
<script type="text/javascript" src="http://apis.google.com/js/plusone.js">
  {lang: 'ja'}
</script>

<!-- Place this tag where you want the +1 button to render -->
<g:plusone size="medium"></g:plusone>

あとはこのコードのコメントにあるとおりにすればOK。
外観→テーマ編集で
ヘッダー(header.php)のの直前に上の埋め込みコードの前半部分を貼り付ける。

<script type="text/javascript" src="http://apis.google.com/js/plusone.js">
  {lang: 'ja'}
</script>

単一記事の投稿(single.php)で表示したい部分に後半の

<g:plusone size="medium"></g:plusone>

を貼り付ければOK。

ところで、このブログのホームには記事が何件も並んでるけど、メインインデックスのテンプレート(index.php)に上のコードをそのまま貼り付けると、
記事ごとに+1ボタンをつけたつもりが、どれを押してもホームのURLに対しての+1になってしまう。

そんなときは、Wordpressのメインインデックスのテンプレート(index.php)で、href属性に記事のパーマリンクを指定すれば、個別の記事ごとへの+1ボタンが作れるよ。

<g:plusone size="medium" href="<?php the_permalink(); ?>"></g:plusone>

このURLを作為的にどこかのURLにしておけば、そうとは知らないユーザーが見ているページに+1をつけたつもりがほかのページがイチオシされちゃうわけだね。

たとえば、
個別記事の+1ボタンのhrefにすべてサイトのホームのURLを指定しておけば、どの記事で+1を押されてもサイト全体の+1として集約したりできるね。
これはFacebookのいいね!やTwitterのボタンでも同様だね。

その他の詳しい属性などについては、

+1 ボタンをサイトに追加(Google Code)

を見てくださいね。

CaboChaの文字コードRecompileしてもうまくいかない、そんなとき

CaboCha 0.60pre4 Windows版で辞書の文字コードを変えようと思ったのだけどうまくいかなかったときの話 CaboChaをインストールすると、スタートメニューには

  • Recompile SHIFT-JIS Model
  • Recompile UTF-8 Dictionary というのが用意されているのだけれど、これをこのまま実行してもCaboChaがうまく動作しないことがある。

症状

たとえば、文字コードをUTF-8からSHIFT-JISに変えようと思って「Recompile SHIFT-JIS Model」を実行。特にエラーもなく終了したので、CaboChaを実行すると、

morph.cpp(108) [charset() == decode_charset(dinfo-&gt;charset)] Incompatible charse
t: MeCab charset is SHIFT-JIS, Your charset is UTF8

となり係り受け解析ができない。

原因

Windows Vista以降で導入されたユーザーアカウント制御UAC(User Account Control)により、C:\Program Files\CaboCha\model\charset-file.txtの書き換えに失敗している。

C:\Program Files\CaboCha\model>echo SHIFT-JIS 1&gt;charset-file.txt
アクセスが拒否されました。

対策

Recompileのバッチ実行後に直接C:\Program Files\CaboCha\model\charset-file.txtのファイルを書き換える。 もしくは、 C:\Program Files\CaboCha\model\mkmodel.batの1行目に以下を追加して、”管理者権限で”Recompileのバッチを実行する。

 cd /d %~dp0 

なぜだろう

UACにより書き込みが制限されるのであれば、最初からバッチコマンド自体を管理者権限で実行すればよいのでは? しかし次のようになってしまう。

C:\Windows\system32&gt;..\bin\cabocha-model-index -f SHIFT-JIS -t SHIFT-JIS dep.ipa
.txt dep.ipa.model
指定されたパスが見つかりません。

C:\Windows\system32&gt;..\bin\cabocha-model-index -f SHIFT-JIS -t SHIFT-JIS chunk.i
pa.txt chunk.ipa.model
指定されたパスが見つかりません。

C:\Windows\system32&gt;..\bin\cabocha-model-index -f SHIFT-JIS -t SHIFT-JIS ne.ipa.
txt ne.ipa.model
指定されたパスが見つかりません。

C:\Windows\system32&gt;echo SHIFT-JIS 1&gt;charset-file.txt

実行ディレクトリが**C:\Windows\system32**になってしまうのだ。 そこで、バッチの先頭で実行ディレクトリに一旦移動する必要がある。それが上で追加したcd /d %~dp0だ。

これは他のバッチファイルでもよくハマるので、なんとなく心の片隅に入れとくとよい。

ちなみに毎回管理者として実行するには、 バッチのアイコンを右クリック→プロパティ→ショートカット→詳細設定→管理者として実行にチェック

一度に複数のリモートリポジトリにgit pushする方法

コマンドひとつで複数のリモートリポジトリにgit pushしたい、そんなとき。

作業中リポジトリの.git/configを直接編集して、push先のurlを複数書いちゃう。
試したのはgit version 1.5.6.5だよ。

[remote "foobar"]
        url = /hoge/foo.git
        url = /hoge/bar.git

あとはリモートリポジトリfoobarにpushすれば、foo.gitとbar.gitにpushされるよ。
でもgit remote -vとかgit showしたときに

warning: Remote origin has more than one URL

って怒られるけどね。
git config -l なら内容を確認できるよ。

remote.foobar.url=/hoge/foo.git
remote.foobar.url=/hoge/bar.git

わけわかんなくなるから複数登録するときはpush用にした方がいいかもね。

Hudson Growl Pluginでビルド結果をGrowlへ通知

Hudsonのビルド結果をGrowlに通知するプラグインGrowl Pluginを試してみたよ。

HudsonGrowl

Hudson Growl pluginのインストール

  1. Hudsonの管理>>プラグインの管理>>利用可能タブを選択
  2. Hudson Growl pluginを探してチェックを入れる
    (利用可能タブに見つからない場合はインストール済みタブを確認してみる。)
  3. 最下部の「インストール」ボタンを押す
  4. インストールが完了したら「ジョブが実行でなければ再起動」ボタンを押してHudsonを再起動
  5. 再起動したらHudsonの管理>>プラグインの管理>>インストール済みタブでHudson Growl pluginが有効化されていることを確認

Hudson側の設定

システム設定

Hudsonの管理>システムの設定>Global Growl Settingsにパスワードを入力して保存する。ここでは仮にpasswordと入力する。
Growl側で既にパスワード設定している場合はそのパスワードを入力すること(Growl側のパスワード設定については後述)。

Global Growl Setting
「失敗したときと回復したときだけ通知」する場合は「Only Growl on Failure or Recovery?」にチェック。

プロジェクトの設定

各プロジェクトの設定でビルド後の処理に「Growl」が追加されてるのでチェックを入れ、通知するマシンのIPアドレスを入力する。
私の場合、VirtualBoxのゲストOSでhudsonを実行していて、ホストOSがMac OSX(Growlの通知先)なので、192.168.56.1と入力したよ。

Hudson Growl IP Setting


「高度な設定」を押すと「失敗したときと回復したときだけ通知」するかどうかを選べるよ。

Growl側の設定

MacのGrowl1.2.1の場合で説明するよ。

  1. Growlのアイコンをクリックして「Open Growl Preferences…」を選択するかMacの「システム環境設定」→「その他」→「Growl」を選択
  2. 「ネットワーク」を選択して、「受信される通知を聞く」にチェック、「リモートアプリケーション登録を許可」にチェック。
    サーバパスワードにパスワードpasswordを入れる。このパスワードはHudson側のシステム設定で入力したパスワードだよ。
    既にGrowl側にパスワードが設定されている人は、そのパスワードをHudson側のシステム設定で指定してね。

Growl Network Setting

通知の確認

ビルド実行してみる。初めて実行したときはキーチェーンがアクセスを許可するか聞いてくるので、「許可」あるいは「常に許可」
GrowlKeyChain

以下のようにプロジェクト名、ステータス、ビルド番号、URLが通知される。
GrowlNotify

通知スタイルを個別に設定したい場合は、Growlの設定で「アプリケーション」を選択すると「Growler」というのがリストにいると思うので、これを選んで設定を押すと編集できるよ。
Growler
重要なプロジェクトの場合他の通知に紛れて見逃さないように、目立つ通知方法にするといいかもよ。sticky notificationにするとかね。
Hudsonの失敗ビルドのRSSをSafariにブックマークしてGrowlSafari(GrowlをダウンロードするとExtraに入ってる)で通知とかやってたんだけど、こっちの方がSafariの他の通知と切り分けられるのでいいね。

timeコマンドの結果をファイルへ出力する

timeコマンドの結果をファイルへ出力するやり方を間違えたのでメモ。
ちなみにbash。

やること

a.outを実行したときの出力とそれにかかった時間をlogfileへ出力する

ダメな例

time ./a.out > logfile
time ./a.out | tee logfile

上がまるっとリダイレクトしちゃうケースで、下はteeで標準出力にも表示しながら実行するケース。
散々時間かけて実行したのに、後でlogfileを見てみたらガッカリ。timeの出力だけはlogfileには書き込まれてない。

timeの結果は標準エラー出力

なのでした。
標準エラー出力も標準出力と一緒にlogfileに書き出さないとダメだね。

まだダメな例

というわけで標準エラー出力も併せてリダイレクトするよ

time ./a.out >& logfile
time ./a.out > logfile 2>&1
time ./a.out 2>&1 | tee logfile

しかし、これもダメ。
./a.out >& logfile
./a.out > logfile 2>&1
./a.out 2>&1 | tee logfile
といったtimeコマンド後ろに書いた「a.outコマンドの実行結果をエラー出力も含めてlogfileに書き出す」のtimeを計っちゃうわけ。だからtimeコマンドの結果はlogfileには書き込まれないよ。

OKな例

やりたい事は「time ./a.out」の出力をlogfileに書くんだから…

(time ./a.out) >& logfile
(time ./a.out) > logfile 2&>1
(time ./a.out) 2>&1 | tee logfile

括弧で囲んじゃえー。これでうまく行く。つまりサブシェルで実行するのです。
ちなみに最近のbashは>&じゃなくて&>でも大丈夫なのね。

コマンドをグループ化する{ ;}でもOKみたい。

{ time ./a.out ; } >& logfile
{ time ./a.out ; } > logfile 2&1
{ time ./a.out ; } 2>&1 | tee logfile

{ の後には必ずスペースを入れようね。スペースいれないと、-bash: syntax error near unexpected token `}’ って言われちゃうよ。あとセミコロン;も忘れずに。

/usr/bin/time

ところで、bash組み込みのtimeとは別にGNUのtimeコマンドというのもあるよ。/usr/bin/timeとフルパスで書いてやると実行できる。
これもbash組み込みのtime同様、標準エラー出力に結果を出力するんだけど、サブシェルで実行しなくても、

/usr/bin/time ./a.out >& logfile
/usr/bin/time ./a.out > logfile 2>&1
/usr/bin/time ./a.out 2>&1 | tee logfile

と、括弧つけなくても大丈夫。もちろん括弧つけてもいい。
それに、ちゃんとファイル出力オプション-oがあるよ。

/usr/bin/time -o logfile ./a.out

でもこれだとtimeの結果しか書き込まれないので、追記オプション-aをつけて

/usr/bin/time -a -o logfile ./a.out > logfile

とやればいいっぽい(おそらく「./a.out > logfile」のtimeなんだろうけど)。

bashのtimeより詳細なデータが出るし、出力フォーマットの指定とかいろいろ柔軟に操作できるコマンドなので覚えておくとよいかもしれないね。
詳しくはman timeで。bashのtimeについてはhelp timeで。

改行を置換したい

改行を置換したいときのメモだよ。
改行コードCR+LFからCRを取り除くとかいう話ではなくて、改行そのものを置換したいときのメモ。CRは入ってない前提。
コマンドのバージョンとか動作環境によってはうまく動かないこともあるかもしれない。

【例】改行をカンマ’,'に置換する

A
B
C

というファイルを

A,B,C

のように書き換えたいという例でお話しする。


エディタで

Emacs

M-x replace-string Replace string:

のところでC-q C-jと入力すると改行コードを引用できて、コマンド行が改行される。Enterで決定すると

Replace string with ^J with:,

となる。改行は^Jで表されている。置換先のカンマ’,'を入力してEnterで決定すれば、現在行以下の改行がすべてカンマに置換される。

Vim

:%s/\n//g

コロンを押してコマンドモードにして%でファイル全体を指定。
%の代わりに1,$と書いてもよい。1行目から最後の行までという意味。
もし置換ではなく改行削除して行を連結するだけなら、J(Shift+j)を押しっぱなしってのもひとつの手。

コマンドラインで

エディタを開かずにコマンドラインだけで済ませたいときもある。
filename は改行を含むテキストファイル。
標準出力に表示するだけなので、必要があれば > newfilename とかやって新しいファイル名を指定して出力してね。
元と同じファイル名に吐き出して消しちゃうっていうのはやりがちなミスなので気をつけて。

tr

以上は代表的なエディタ上での置換方法だったけど、コマンドラインで済ませたいときはtrがいちばんラクかも。

tr '\n' ',' < filename
あるいは
tr '\012' ',' < filename

改行を削除したいときはーdオプション。

tr -d '\n' < filename
あるいは
tr -d '\012' < filename

awk

awk -F\n -v ORS=','  '{print}'  filename

-Fで区切り文字指定、 -v ORSで出力の区切り文字指定。

sed

sedは1行ごとに処理するのは得意なんだけど、改行をまたぐ処理はわりと面倒くさい。
たとえば上の例とは逆にカンマを改行に変えるのであれば

sed 's/,/\n/g' filename
あるいは
sed 's/,/\        ←バックスラッシュの後で普通にEnterを押す
> /g' filename

でうまくいく。1行目のバックスラッシュのあとに普通に改行ボタン押せば次の行にプロンプトが出るので、続きを入力すればよい。
ところが例題の処理をやろうとして

sed 's/\n/,/g' filename
あるいは
sed 's/\
> /,/g' filename

と書いてもうまくいかないワケ。
じゃあどうするかというと、Nコマンドというのを使えば次の行も読み込めるので、これを最後までループでまわして全体を読み込んでから置換する。

sed ':loop; N; $!b loop; ;s/\n/,/g' filename
あるいは
sed ':loop; N; $!b loop; ;s/\
> /,/g' filename

ただGNUのsedだとうまくいくけど、BSDのsedだとこのやり方でもうまくいかないかも。
[参考]sed の使い方 4.3 改行をすべて削除

Perl

perl -pe 's/\n/,/g' filename

ruby

ruby -pe 'gsub(/\n/,",")'  filename