カテゴリー : 2008年 4月

複数ファイルの中身を一括置換するには


複数のファイルをまとめて置き換えたいときは sed を使うと便利です。
 
たとえばこのようにすると指定したディレクトリの中のすべての .html ファイルの内容を 2007年 から 2008 年に書き換えることができます。

for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
  mv $i $i.bak
  sed -e ‘s/2007年/2008年/g’ $i.bak > $i
done

影響があったファイルの一覧を得るには次のようにします

for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
  diff -q $i.bak $i
done

影響があったファイルの内容を比較する場合も diff を使います。

for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
  echo $i
  diff $i.bak $i
done

問題に気づいて元に戻したいときは *.bak を移動させれば元に戻ります。

for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
  mv $i.bak $i
done

変更が問題なければ .bak ファイルを削除して置換完了です。

for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
  rm $i.bak
done

参考:
sed の使い方

sed の使い方


書式:

sed -e ‘コマンド1′ [-e 'コマンド2' [...]] ['ファイル名']

指定したファイル(省略した場合は標準入力)を入力テキストとして読み込み、
-e で指定したスクリプトを順番に実行して標準出力に書き出します。
 
-e で指定できる書式は次のようなものがあります。
 
■命令のみ指定するタイプ( -e 命令 ):

-e p

行バッファの内容を出力(Print)する。バッファの内容は操作しないため、-ep -ep のように複数指定すると指定回出力されます。バッファの消去には後述の d を使用します。また、全てのスクリプトを実行したあとにもバッファ内容が出力されます。

-e d

行バッファの内容を消去(Delete)する。通常、p 命令と組み合わせて利用します。
 
■正規表現パターン + 処理内容指定をするタイプ(-e /正規表現/命令):

-e /^foo/p

foo から始まる行を出力します。

-e ‘/boO$/d’

boO で終わる行をバッファから削除します。

-e ‘/[J][j]ohn/p’

John または john が含まれる行を出力します。
 
■正規表現による置換(-e s/正規表現/置換内容/オプション)

-e s/foo/boo/

各行バッファで最初に見つかった foo を boo に置換します。

-e ‘s/a/A/g’

バッファ中の全ての a を A に置換します。

-e s/john/JOHN/ig

バッファ中の全ての john(大文字小文字問わない)を大文字の JOHN に統一します。
 
例:

echo “Hallo, world” | sed -e s/a/e/

typo を訂正する(Hallo -> Hello)。

cat /var/log/httpd/access_log | sed -e ‘/GET/p’ -e ‘/^127\.0\.0\.1/p’ -ed

Apache のローカルからの GET アクセスを抽出する。

右クリック→新規作成からテキストファイルが消えた


XP の話。
検索してみると同じ症状の方が結構いたので解決方法のメモを残しておきます。
 
原因A: レジストリの HKEY_CLASSES_ROOT\.txt の ShellNew キーの内容が正しくない、もしくは不足している

HKEY_CLASSES_ROOT\.txt\ShellNew というキーがあり、NullFile という空の文字列値があるか?

ない場合は作成する。
 
原因B: レジストリの HKEY_CLASSES_ROOT\.txt の(既定)の値が正しくない
HKEY_CLASSES_ROOT\.txt の既定の値は txtfile です。
これ以外の値に書き換わっている場合(txt_auto_fileになっている、などの場合)は txtfile に変更することで解決する場合があります。
 
原因C: レジストリの HKEY_CLASSES_ROOT\.txt の PerceivedType キーの内容が正しくない、もしくは不足している

HKEY_CLASSES_ROOT\.txt\PerceivedType というキーがあり、text という文字列が設定されているか?

ない場合は作成する。
 
原因D: レジストリの HKEY_CLASSES_ROOT\Directory 以下が Windows Update で書き換わった
( http://pub.ne.jp/pchitorigoto/?entry_id=1145705 より。)

HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\New\

の(既定)の値が

{D969A300-E7FF-11d0-A93B-00A0C90F2719}

以外になっていると新規作成が正しく動作しない現象が発生するようです。
 
どうしても解決しない場合:
Windows XP なら、こちらのサイトから、「TXT File Association Fix」をダウンロードして実行するとレジストリキーを修復できます。
ただし、.txt ファイル関係の設定をリセットするためテキストファイルへの関連付け等が外れてしまいます。
参考:
New command missing in Windows Explorer(Microsoft サポートオンライン:英語)
Windowss XP File Association Fixes

tips – PuTTY でコマンドライン – サーバごとに接続設定を変える


PuTTY は SSH と互換のコマンドライン引数を持っているため、以下のようにしてコマンドラインからユーザ foo, ドメイン example.com でログインできます。

putty foo@example.com

 
環境変数 PATH に putty.exe (または puttyjp.exe)へのパスを通しておけば、Windows の「ファイル名を指定して実行(Windowsキー + Rキー)」で実行できるためかなり便利です。
 
GUIでのログインと同様、サーバごとに秘密鍵や文字コードの設定−保存(ストア)されたセッション−を切り替えてログインしたい場合は、

putty -load “セッション名”

とすると指定した設定(セッション)をコマンドラインから読み込んでログインすることができます。セッション名を user@hostname の書式で設定しておけば

putty -load foo@example.com

のように通常のログインに -load を加えるだけでよいので管理、利用が容易になります。
  
参考:
PuTTY でデフォルト設定を変更する(過去記事)
ssh -R の応用例(過去記事)
ssh を任意のポート、プロトコルの proxy にする(過去記事)

.htaccess で PHP の表示言語を切り替える


php_value, php_flag を使って自動文字コード変換をする tips です。
  
.htaccess:

# ソースの文字コード(SJIS, EUC-JP, UTF-8 など mb_convert_encoding()で指定する書式)
php_value mbstring.internal_encoding UTF-8
# ヘッダで表明する出力文字コード(Shift_JIS, EUC-JP, UTF-8 など Content-Type で指定する書式)
php_value default_charset Shift_JIS
# 変換に使う出力文字コード(mb_convert_encoding()で指定する書式)
php_value mbstring.http_output SJIS
# 変換文字コードが属する言語
php_value mbstring.language Japanese
# フォームなどの入力文字コードは自動判別させる
php_value mbstring.http_input auto
# 入力の自動変換を有効化(Off で無効化)
php_flag mbstring.encoding_translation On
# 出力の自動変換を有効化(空値で無効化)
php_value output_handler mb_output_handler

なお、動作には

1.CGI モードではなく PHP-CLIモードで動いていること
2. httpd.conf で AllowOverride Options または AllowOverride All など Options の変更ができるように設定されていること。

が必要です。


ちなみに余談ですが、同じことを .htaccess なしでやろうとした場合は次のようになります。

<?php
// 自動変換処理
mb_language(“Japanese”);
// ソース文字コード
mb_internal_encoding(“UTF-8″);
// 出力文字コード
mb_http_output(“SJIS”);
header(“Content-Type:text/html;charset=Shift_JIS”);
 
// mb_output_handler で出力をフィルタリング
ob_start(“mb_output_handler”);
register_shutdown_function(‘ob_end_flush’);
 
// 入力をフィルタリング
// (mb_convert_encoding($value, mb_internal_encoding(), “auto, UTF-8″);
// を使い、 $_REQUEST, $_GET, $_POST, $_COOKIE など入力変数を変換すればエミュレートできるが
// 長くなるので省略)
 
// —————————–
// あとは普通の処理
 
echo “はろーわーるど\n”;

参考:
AllowOverride ディレクティブ(Apache 2.2 リファレンス)
PHP 出力制御関数(php.net)

AllowOverride が効かない


<Directory ~ “^/path/to/(htdocs|secure)/”>
AllowOverride All
</Directory>

こういう設定で、 AllowOverride All してるのに .htaccess が無視されていておかしいなと首を傾げていたところ、マニュアルを見て納得。

AllowOverride ディレクティブ:
(中略)
<Directory> セクションでのみ使用可能
AllowOverride は正規表現無しの<Directory> セクションでのみ有効で、<Location> や <DirectoryMatch> や <Files> セクションでは無効です。

なーるほど…。
ただ複数書くのが面倒、っていう理由で正規表現形式にしていたので、<Directory> を複数に分けて解決。

トラブルシューティング – portsdb.rb で cross-thread violation on rb_gc()


ある日 portversion と portupgrade で ports をアップデートしようとしたところ、portsdb.rb で次のようなエラーが出るようになり portupgrade 関係のプログラムがまったく動作しなくなってしまった。

/usr/local/lib/ruby/site_ruby/1.8/portsdb.rb:116:[BUG] cross-thread violation on rb_gc()
ruby 1.8.6 (2007-09-24) [i386-freebsd7]
 
SIGABRT (Abort trap: 6)

ちなみに環境は FreeBSD 7.0 + ruby_1.8.6_p111_2,1。
ports から ruby, portupgrade 入れなおしても
ソースを辿ったところ, libpthread が有効になっている時のみこのエラーが出るようになっているということが判明したため、

# cd /usr/ports/lang/ruby18
# make config

で LIB_PTHREAD を無効化した上で make install しなおしたところ無事解決しました。

tips – 色々なプロトコルをネットワークドライブに使う


最近は便利な世の中になったもので、色々なストレージサービスが増えてきましたね。
エクスプローラの「ネットワークドライブの割り当て」機能を使うとネットワークごしのドライブでも “Z:\foo.txt” など仮想のドライブとして認識できるため、ファイルの編集、作成、削除など、ほとんどのアプリケーションでの操作がまるでローカルHDDのように扱えるようになります。そこで、色々なネットワークストレージをネットワークドライブ化できるソフトウェア/方法についてまとめてみました。
 


- Gmail をネットワークドライブ化
Gmail Drive shell extension
エクスプローラのシェル拡張として動作するようです。
日本語での解説は「臨機応変? – Gmailをネットワークドライブとして使ってみる」が参考になります。


- FTP をネットワークドライブ化
Novell NetDrive というフリーソフトを使うと FTP, WebDAV プロトコルが使えるサーバをネットワークドライブにできます。ライセンスを他社に譲渡し、WebDriveという有償の製品になったため、開発元の novell.com からはダウンロードできなくなっていますが、サーチエンジンで検索すると見つかります。一応うちにも置いておきます。
 
ミラー:netdrive.exe をダウンロード
 
なお、Windows Vista の場合は NetDrive が非対応のため WebDrive を使う必要があります。
ネットワークドライブではなく “ftp://username:password@hostname/path”の形式ならばエクスプローラ標準でフォルダのように仮想的に扱うことができますが、当然ですが、こちらはFTP対応していないアプリケーションからはアクセスできません。


- WebDAV をネットワークドライブ化
前述の NetDrive, WebDrive が WebDAV に対応しています。
また、Windows Vista の場合は標準で対応しているようです。


- Amazon S3(Simple Storage Service) をネットワークドライブ化
Amazon S3 は Amazon が提供する 1GB あたり 15セントで使えるネットワークストレージサービス。容量制限はありません。
 
Jungle Diskというシェアウェアでネットワークドライブ化できます。
また、前述の WebDrive も Amazon S3 に対応しているようです。


- SFTP,SCP, Frontpage server をネットワークドライブ化
前述の WebDrive がこれらに対応しています。


- Xdrive をネットワークドライブ化
AOL が提供している Xdrive というフリーのストレージサービス。
1アカウントあたり 5GB のストレージを無料で利用できます。
Downloads から Xdrive Desktop をダウンロードすればネットワークドライブ化できそう。


- Windows Live SkyDrive をネットワークドライブ化
Microsoft が提供する Windows Live SkyDrive というフリーのストレージサービス。
hotmail のアカウントごとに 5GB のストレージが無料で利用できます。
今のところは無理そう。

スパムフィルタの適用実績を調べる


Postfix の main.cf で

smtpd_client_restrictions =
    reject_rbl_client bl.spamcop.net,
    # 中略…
    permit

のように複数のブラックリストデータベース(MAPS RBL)を設定していて、実際どれが使われているのか判断したい場合、以下のようにして実際に何件のメールについてブロックが適用されたか調べられます。
 

$ cat /var/log/maillog | perl -ne ‘if(/blocked using (.+?);/){print $1.”\n”;}’ | sort | uniq -c

結果例:

$ cat /var/log/maillog | perl -ne ‘if(/blocked using (.+?);/){print $1.”\n”;}’ | sort | uniq -c
  45 bl.spamcop.net
   4 list.dsbl.org
   7 sbl-xbl.spamhaus.org