最近覚えたgrepのオプション 「C」
この手の話は、なんだよそんなことも知らなかったのかよ、的な話ではありますが。
grepコマンドのオプションにCってのがあるのを最近知りました。バージョン依存だったりするかもしれませんが、その辺を調べる気はありません。
$ grep -C1 hoge xxxx.log
などとやりますと、xxxx.logから「hoge」を含む行とその前後1行が抽出できます。
$ grep -C5 hoge xxxx.log
なら前後5行。
で、今更help見てみたら、A(after)とかB(before)もあるらしいので、一緒に覚えちゃいましょう。僕も今覚えました。
役に立つシチュエーションは結構あると思いますです。
追記
さらにhelp見てたら、-CのCは省略できるらしい。つまり
$ grep -C5 hoge xxxx.log
と
$ grep -5 hoge xxxx.log
は同じだよ、と。
たむらぱんワンマンライブ@恵比寿LIQUIDROOM
今回はsaku sakuからのお花はなかったのかなぁ。僕が見つけられなかっただけか。ゲスト出演もしてるので、送られてて不思議はないと思うんだけど。と いうことでお花写真はありません(ちゃんといくつか来てましたよ。覚えてるのだとダ・ヴィンチ編集部とか)。
前回の下北のこともあって直前の期待値はそれほど大きくなかった、からってだけではなく、とても楽しいライブでした。
以下、セットリストにそって。
- スポンジ
- ぶっ飛ばすぞ
- まずはノリのいい曲で会場を盛り上げる。まぁ、パッと見それほど盛り上がった感はしないんですけどね。たむらぱんファンは皆さん割とおとなしいので。ぶっ飛ばすぞをライブで観るのは久しぶり。
- バンブー
- アミリオン
- ファイト
- 「ファイト」は、CMにも使われている曲で、鉄腕DASHをほぼ毎週見ている僕は、その部分だけは何度も聴いていました。今回はじめてフルバージョンを聴いたのですが、とんでもない変態曲で、「マウンテン」を超えてます。早期音源化希望。
- ズンダ
- ごめん
- オーディエンス参加型曲が2曲続く。
- WARAW
- ラフ
- 「WARAW」生で聴いてみたら予想外によくて、ちょっと評価を変えた。「ラフ」の間奏の時はどうしても生本さんを注視してしまう僕でしたが、いつ も通りのピック投げをみて満足。
- 関白宣言
- フレフレ
- この2曲の前にMCがありまして、大体いつもライブで「フレフレ」の前には、これは平成の「関白宣言」を~~的なことを言うので、あーフレフレね 、とか思ってたらまさかの「関白宣言」カバー。これがまたグッときた。実にいい。ちょっと涙出た。いやホント。
- しんぱい
- 新曲。初めて聴いた頃よりかなり好きになってきている。
- ハレーション
- 夏に向けての1曲。
- ライ・クア・バード
- 僕がライブで聴くのはノウニウノウンの収録曲全部やったバンタム以来。色々曲も増えてきて、バリエーションも増えてなにより。
- SOS
- オーディエンス参加型その3。「ピース」は大体忘れます。で、みんながピースしてるの見て、ビクトリーから参加するという。ここで本編は終わり 。ここからアンコール
- 回転木馬
- ピアノの横山さんだけ出てきたので、「とんだって」かなぁ、終盤にとんだってもってくると、喉きついんだけどなぁ、とか思ったてら、こっち。まぁ、これはこれで1ヶ所高音きつそうなところがあって、そこが近づくにつれてドキドキしちゃったんだけど、今回は大丈夫でした。
- 責めないデイ
- ジェットコースター
- 回転木馬のあとは、紹介とともにその他のバンドメンバーを呼び寄せて、ラスト2曲。
全18曲とちょっと短めではありましたが、今回はアルバムの発売とかが絡んでないからか、新旧とりまぜ+カバーもありで、僕的には大変満足できるステー ジでした。それと、仕事終わってから行ったから入場が遅くなったこともあるけど、立ち位置が後ろの方で前回のLIQUIDROOMみたいに音に酔うこともなく気持よく帰ることができました。リベンジ成功。
しんぱい
本日発売の7thシングル。タワーレコードで購入すると、招待ライブの応募券がついてるとのことで、タワーレコードで予約して購入しました。まぁ、ここ 最近はCDはだいたいタワレコで買ってますけどね。
最初聞いたときは、あんまり好きじゃありませんでした。昨日から今日にかけて何度か聞いて、少しずつアリかなと思うようにもなってきましたけど。カップリングの「WARAW」の方は、インディーズ時代の割と古い曲とのことで、実にたむらぱんぽい曲。実はこれも第一印象的には普通レベル。
ただ、トラック3以降に収録されている、「ラフ」、「バンブー」、「フレフレ」、「ゼロ」のLive version(音源は3月のパンダフルツアーファイナルのLIQUIDROOMだそうです)はかなりお買い得気分。「ラフ」と「ゼロ」は個人的に好きな曲TOP3に入る曲ですし。 ちなみにTOP3のもう一曲は「恋は四角」。
ちなみにamazonのページには「たむらぱんからのメッセージ」として、ムービーへのリンクもあったりしますので、ファ ンの方は一度ご覧ください。
ついででなんですが、こんな企画物も紹介しておきます。
この中の1曲、「天使のウィンク」をたむらぱんが歌っています。僕はアルバム1枚買う気にはならなかったので、moraで、1曲だけ購入しました。専用アプリとか入れなきゃいけないし、IEしか対応してないし、iPodで聴くためにはいったんCDに焼かなきゃいけなくてCD-Rの在庫 が家になかったのでわざわざ買いに行ったり、と色々面倒でしたけど。
労力考えたら2000円出して丸ごと買った方がよかったかもしれません。
Togetterをフィルタリングするuser.js
http://mattz.xii.jp/sites/default/files/togetter-filter_100.js
http://mattz.xii.jp/sites/default/files/togetter-filter_100b1.js
出来ること
- 指定したIDによるまとめを一覧から除外
- 指定したキーワードをまとめタイトルに含むまとめを一覧から除外
- 指定したID(1とは別管理です)によるコメントをコメント欄から除外
- 指定したIDのtweetを一時的に抽出/非表示/強調する機能を追加(1.0.0で追加)
簡単な使い方
user.jsそのものの使い方は省略します。
まとめのタイトルによるフィルタリング
このuser.jsを有効な状態でTogetterの「注目のまとめ」などの一覧ページを開くと、各まとめのタイトルの左に[NGワード登録]というボタンが表示されま す。
これをクリックすると、入力用のダイアログが開きます。初期状態ではそのまとめのタイトルが既に入力済みの状態になっていますので、適宜編集して[OK]ボタンを押すと、そこで登録した単語(文字列)を含むまとめは、「NGタイトルにより非表示にされています(クリックで再表示)」という表示に置き換わります。
これをクリックすると、フィルタリング対象のまとめでも表示し、登録してしまったNGワードを削除することもできます。
なお、「,」半角のカンマはNGワードに使えません。
まとめた人のIDによるフィルタリング
このuser.jsを有効な状態でTogetterの「注目のまとめ」などの一覧ページを開き、各まとめのまとめた人のアイコンをクリックすると、「このユーザの作 成したまとめを非表示にしますか?:○○」というダイアログが開きます。
[OK]を押すと、以後その人の作成したまとめは、一覧に表示されなくなります。復帰させたい場合は、その人のプロフィールページ(http://togetter.com/id/○○)に行くと、ページの左上の方に「このユーザのまとめは現在フィルタリング対象です。→[解除]」というメッセージが表示されますので、「解除」ボタンをクリックしてください。
コメント欄のIDによるフィルタリング
このuser.jsを有効な状態でTogetterの何かのまとめを開き、コメント欄の誰かのアイコンをクリックすると、「このユーザのコメントを非表示にしますか ?:○○」というダイアログが開きます。
[OK]を押すと、以後その人のコメントは、どのまとめページにも表示されなくなります。復帰させたい場合は、その人のプロフィールページ(http://togetter.com/id/○○)に行くと、ページの左下の方に「このユーザのコメントは現在フィルタリング対象です。→[解除]」というメッセージが表示されますので、「解除」ボタンをクリックしてください。
特定IDの抽出/非表示/強調
このuser.jsを有効な状態でTogetterの何かのまとめを開き、誰かのつぶやき部分をクリックすると、
このような物が表示されます。
[Pick-up]を押すと、その人のtweetsだけを残して、他の人のtweetを非表示にします。
[Remove]を押すと、Pickupの逆でその人のtweetsを非表示にします。
色付きの■部分を押すと、その人のtweetsのフォントカラーをその色に、背景色をアイボリーに変更して、少し目立つようにします。
やめたいときは「Click (or press [ESC]) to close.」部分をclickするか、Ecsキーを押してください。
また、これらの抽出/非表示/強調はあくまで一時的なもので、ページを読み込み直すと元の状態に戻ります。
Togetter用のuser.js最新版
http://mattz.xii.jp/sites/default/files/togetter_421.js
2011/10/05:いくつか設定項目を追加しました。
http://mattz.xii.jp/sites/default/files/togetter_410.js
2011/06/10:いくつか設定項目を追加しました。
http://mattz.xii.jp/sites/default/files/togetter_401.js
2011/06/06:Togetterのhtmlが変更になったようで「最初から"もっと読む"」が効いていなかったので修正しました。
http://mattz.xii.jp/sites/default/files/togetter_400.js
多少修正して、とりあえず4.0.0としてはフィックスします。
http://mattz.xii.jp/sites/default/files/togetter_400b1.js
とりあえず版。Togetterさん、リニューアルで以前に比べればだいぶすっきりしましたけど、個人的にはまだ要らない(サービスとし て必要なのは分かりますが)要素が多いので、その辺をすっきりするだけです。まぁ、ほとんどの項目はuser.cssで消せるんですけどね。
スクリプト適用前
スクリプトを適用し、全ての設定を有効にした場合
フィルタリングしたりするのは、別ファイルに分けようかと検討中。
ライブみてきました
いつも通りたむらぱんのライブだったりする訳ですけど、いつもと違うところもあって、今回はワンマンじゃなくてHALCALIさんと一緒。一緒っていっても 別に一緒に歌ったりする訳ではないですけどね。会場は下北沢GARDENというハコで、今回のライブのページがこちら→~Special two sets that blooms in shimokitazawa~
構成は前半がたむらぱんで、機材の入れ替えがあって後半がHALCALIというもの でした。
前半のたむらぱんパートは、新曲の「しんぱい」の初披露などはあったものの、こう言ってはなんですが前回のLIQUID ROOMからそんなに変わってなかった りで、あまり驚きなどはなくて。最近「ノバディノウズ」よくやるのはなんでかなぁ、くらい。2曲目の後のアクシデントについてはあんまり触れないでお きますけど、ちょっとどうなの、とは思いました。あ、あと会場が狭い + 僕の知る限りではクアトロ以来の踏み台ありだったので、たむらさんがよく見え たのは良かったところ。出来ればいつも踏み台で歌ってもらえないかな。
で、1時間弱でたむらぱんパートは終わりで、なんかここで帰っちゃった人が結構いたみたいです。僕はメインはもちろんたむらぱん目当てでしたけど、今 まで全く聴いたことはないとはいえ、HALCALIはHALCALIでどんなもんなのか楽しみにしていたので最後まで観てきましたが、帰っちゃった人、多分損しましたよ。
だって、この際なので正直に書きますけど、後半のHALCALIさんのステージの方が楽しかったですから。ジャンル的にはヒップホップだそうですが、今まで ヒップホップなんて全然聴いたことありませんし、当然ライブなんか初めてです。HALCALIさんの曲も全然知りませんでしたけど、なんだか聴いててウキウ キ・ワクワクする感じでとてもよかったです。HALCALIファンなんだろうな、って人が近くで楽しそうに踊ってたので、そのノリ見ながら僕も適当に体揺ら したりしてました。たむらーのみんなも、もうちょっとだけ大きく体動かしたらいいのになぁ、などとも思いましたけど、楽しみ方は人それぞれですしね。
音楽のジャンルとしてはあまり好みではないので、HALCALIのCD買ったりすることは多分ないかな、なんて思うんですが、ライブはまた観てみたい気もしま す。
オチも何も無いですが、今日(日付的には昨日だけど)のライブの感想はこんな感じです。
「なんだっけ」でググると「もしかして:」を提示してくれるuser.js for Opera
なんだっけ、でくぐったら「もしかして:」で検索ワードだしてきたらこわい
に触発された。力不足でクロスブラウザにはできなかった。
追記その5:「Opera9.6 から「安全でなくなった」 UserJavaScript があるけ どイコール「危険」というわけでもない話」を併せてお読みください。
拾う単語は、Yahoo!の急上昇ワードランキングから取得するようにした。Twitterの日本のTrendsから、とか、他の例えばランダム単語APIなんかでもいい。ただしその場合は若干スクリプトを変更する必要がある。Google TrendsのAPI欲しいんだけどないのかな?
あと、xmlをGETしてくるところは http://javascript.g.hatena.ne.jp/edvakf/20100329/1269881699 をほぼそのまま利用させてもらった。edvakfさんに感 謝。
追記その4:追記の1~3はそうはいってもやっぱり恥ずかしいのでhtmlのコメントとして隠した。とにかくコメント欄参照のこと。
// ==UserScript==
// @name nandakke.js
// @author mattz
// @namespace http://mattz.xii.jp
// @license public domain
// @description 「なんだっけ」でググると「もしかして:」を提示してくれるuser.js for Opera
// @published 2011-05-13
// @version 0.0.2
// @include http://www.google.com/search?*
// @include http://www.google.co.jp/search?*
// ==/UserScript==
(function(){
var _document = document;
var call = Function.prototype.call,
indexOf = Array.prototype.indexOf,
splice = Array.prototype.splice,
preventDefault = Event.prototype.preventDefault,
removeChild = Node.prototype.removeChild,
createElement = Document.prototype.createElement,
push = Array.prototype.push,
appendChild = Node.prototype.appendChild,
parseFromString = DOMParser.prototype.parseFromString,
getElementsByTagName = Document.prototype.getElementsByTagName,
parseInt = window.parseInt,
random = Math.random,
encodeURIComponent = window.encodeURIComponent,
setAttribute = Element.prototype.setAttribute,
getElementById = Document.prototype.getElementById,
split = String.prototype.split;
var scripts = [];
var callbacks = [];
opera.addEventListener('BeforeScript', function(e) {
indexOf.call = splice.call = preventDefault.call = removeChild.call = call;
var s = e.element;
var index = indexOf.call(scripts, s);
if (index >= 0) {
callbacks[index].call(null, s.text);
splice.call(scripts, index, 1);
splice.call(callbacks, index, 1);
preventDefault.call(e);
removeChild.call(s.parentNode, s);
}
}, false);
var xGet = function (url, callback) {
createElement.call = appendChild.call = push.call = call;
var s = createElement.call(_document, 'script');
s.src = url;
appendChild.call(_document.body, s);
push.call(scripts, s);
push.call(callbacks, callback);
}
var rand_word = function(xml) {
parseFromString.call = call = setAttribute.call = createElement.call = appendChild.call = getElementById.call = call;
var xmldom = new DOMParser();
xmldom.async = false;
var dom = parseFromString.call(xmldom, xml, "application/xml");
if (! dom) return false;
var is = getElementsByTagName.call(dom, 'item');
var r = parseInt(random() * 20);
var word = is[r].getElementsByTagName('title')[0].textContent;
var b = createElement.call(_document, 'b');
b.textContent = word;
var a = createElement.call(_document, 'a');
a.href = '/search?hl=ja&rls=ja&spell=1&q=' + encodeURIComponent(word);
setAttribute.call(a, 'class', 'spell');
appendChild.call(a, b);
var span = createElement.call(_document, 'span');
span.textContent = 'もしかして: ';
setAttribute.call(span, 'class', 'spell');
setAttribute.call(span, 'style', 'color:#cc0000');
var p = createElement.call(_document, 'p');
setAttribute.call(p, 'class', 'ssp');
appendChild.call(p, span);
appendChild.call(p, a);
appendChild.call(getElementById.call(_document, 'topstuff'), p);
}
var init = function() {
split.call = call;
var a = split.call(location.search, /[\?&]/);
for(var i = 0; i < a.length; i++) {
var q = split.call(a[i], /=/);
if ('q' == q[0] && '%E3%81%AA%E3%82%93%E3%81%A0%E3%81%A3%E3%81%91' == q[1]) {
xGet('http://searchranking.yahoo.co.jp/rss/burst_ranking-rss.xml', rand_word);
return false;
}
}
}
window.addEventListener('DOMContentLoaded', init, false);
})();
タグ
MySQLのDrupal 6からSQLiteのDrupal 7へ
各nodeの移行をすべく色々試行錯誤した。ちなみに本文中の「{hogehoge}」ってやつはテーブル名を表していますが、そもそもこのエントリは基本自分用で、Drupalを全く知らない人は全く想定していません。
まず、Drupal 6のnodeの中身は、基本的に{node}と、{node_revisions}に保存されている。ので、その中身をSelectして、それっぽいテーブルにつっこめばいいだろう、と思ったのだが、Drupal 7には{node}はあっても、{node_revisions}はない。{node_revision}ってのはあったが、本文を保存するカラムがな い。
色々と探してみて、{field_data_body}のようだと思われたので、{node}、{node_revision}、{field_data_body}の各テーブルのそれぞれのカラムに、Drupal 6のDBからSelectした値を入れてみる。結果、nodeの中身は表示されない。
もうちょっと探してみたら、{field_revision_body}というテーブルも見つけたのでそこにもそれらしい値を入れてみたが表示されない。
ここまで来てやっとnodeモジュールのソースを見るという行為に着手。いやまぁ最初にやれって思わないわけではない。というのは置いといて、ソースをざっと見た限りでnode/addするときにupdateしたりinsertしたりするテーブルには他に{history}というのもあるらしいことが分かったので、そこにも値を入 れてみるが表示されない。
もう値が必須なテーブルはないと思うんだけどなぁ、と思いながら、外部からリンクされていて今でも時々アクセスのあるnode(エントリ)から優先して、手作業で中身を移す。
四百いくつかあるエントリの50くらいは手作業で移行しただろうか。そこでめんどくさくて飽きる。どうせめったに参照されることもないし、ほっといてもいんじゃね?という思いに作業を中断し3日ほど放置。
まぁ、ちょっとずつでもやるかなぁと思い直し作業を再開しようと思ったら、なぜか過去のnodeも全て表示できているっぽい。
???
もっとも、データ自体はちゃんとスクリプト書いて必要なテーブルに必要な値は入れたはずなので、元々表示されないほうが不思議だったのだが、何故何もしてないのに表示できるようになったのだろう。Drupalのキャッシュかなぁ?
Operaの設定でおすすめしたいこと
基本的にマウスジェスチャとかショートカットとかは、ほとんど変更しないで使うんですが、どうしても変えずにはいられない設定が少しだけあります。
マウスジェスチャ
マウスジェスチャに関しては1個だけ。標準の設定だと、GestureRight(右クリックしたままマウスを右に動かす)とFlipForward(左クリックを押したまま右 クリック。ロッカージェスチャーともいうんでしたっけ?)のアクションは、同じ「Forward | Fast forward, 0」になっています。これは、「(履歴を)進むけど、進むページがない場合はFast Forward、それも無理ならなにもしない」というものです。同じアクションが違うジェスチャに割り当ててあるのはもったいないので、どちらかの設定を逆にします。
Forward | Fast forward, 0
を
Fast forward, 0 | Forward
こうする。つまり「Fast Forward、できない場合は履歴を進む、それも無理ならなにもしない」です。僕の場合は、FlipForwardの方を変更しています。ひ とつの例としては、検索結果のページからどれかのページを開く場合。開いてみたページがピンと来ないので検索結果に戻り、検索結果の次のページに行きたい、とか言う場合に役に立ちます。最初から別タブで開いとけとかいうツッコミは無しの方向で。これに限らず、履歴上の「次」とサイト構成上の「次」が異なる場合は結構あるので。
ショートカット
F1の割り当ては標準ではヘルプページを開く、ですがヘルプページなど滅多に見ませんので、僕はこれを「go to nickname」に変更しています。で、よく使うブックマークレット(例えばlivedoor clipにclipするとか、livedoorReaderでSubscribeするとか、textareaをリザイズ可能にするとか)は全てニックネームをつけておいて、F1を押して出てくるダイアログに、そのニックネームを入力して使います。
「go to nickname」の標準の割り当てキーはShift+F2で、「go to page」のF2とセットになっててこれはこれでいいとは思うのですが、Shift+というのはやっぱりめんどくさいので、隣のF1を使うことにしました。
これの何がいいかというと、ブックマークのニックネームはOpera Linkで同期できるので、新しくセットアップしたOperaでも、F1の割り当てを1つだけ変更すればすぐにいつもの環境にできることです。この程度であればバックアップとか必要ない。
というか書いてて思いましたけど、おすすめのショートカット変更ではなくて、ブックマークレットにはニックネームをつけよう、とい う方が主題ですよね、どうみても。まぁいいか。
ちなみに以前はCtrl+Qあたりも変更してましたが、最近は「終了を確認する」を有効しているので、特に変更の必要を感じなくなりました。