grepの-oオプションと-Pオプションの組み合わせが便利
$ paste <(cat score | grep -oP '[^\d]+') <(cat score | grep -oP '\d+') | xargs -n 2 #シェル芸
— ぐれ (@grethlen) 2014, 6月 14
上記のようにgrepコマンドを叩いていたら「-oPってオプションなに?」と言われたので。
grep -oPって?
-oオプションとは
--only-matchingの略。マッチした部分のみを抽出するというオプションのこと。
$ echo "123abc456dfg" | grep -o [a-z] a b c d f g
-Pオプションとは
マッチさせる文字列にPerlで使われているものと同じ正規表現(Perl正規表現)をつかえるようにする。PerlのP。
普通の正規表現とPerl正規表現の違いって?
主に以下の3つ。
これらの特徴はPerl正規表現のみであり、 拡張正規表現オプション(-E)をつけたとしても 使うことはできない。
つまり-oPとすれば
$ echo "123abc456dfg" | grep -oP '\d' 1 2 3 4 5 6
どんな時に使える?
grepだけでテキストの「行の抽出」と「切り出し」が同時に行える。
具体例
たとえばこんなexample.xmlという名前のXMLファイルがあったとする。こいつからname要素内のテキスト、それも鍵カッコがついているもののみで、かつ(「」)で囲まれている中身だけを取り出したい。
「Cure Lovely」 「Cure Princess」 「Cure Honey」 「Cure Fortune」 Cure Gorilla
"Cure Gorilla"以外の下のような出力を得たい。さあ、どうする?
Cure Lovely Cure Princess Cure Honey Cure Fortune
- 安直に思いつく方法。
$ cat example.xml | grep '「' | sed 's/.*「//' | sed 's/」.*//g'
$ cat example.xml | xmllint --xpath '//name[contains(./text(),"「")]/text()' - | nkf --numchar-input | sed -r 's/(「|」)/\n/g'
- AWK先生
$ cat example.xml | awk -F'[「」]' 'NF>2{print $2}'
- sed先生
$ cat example.xml | sed -nr '/「/{s/.*「//g;s/」.*//gp}'
実はgrepだけでいける
$ cat example.xml | grep -oP '(?<=「).+(?=」)'
しくみ
Perl正規表現の「先読み・後読み」のパターンで文字列をマッチさせたとしても、 (?~)の中の文字列に関しては、grepの出力時にはマッチした文字列としてみなされない。試しに--colorオプションをつけても、「先読み・後読み」でマッチした部分は色は変化しない。
おそらくUNIXコマンド類の初学段階だと、awkやsedは文字列の「切り出し」、grepは「行の抽出」に使えるという認識になると思う。そして、学んでいくにつれてawkやsedもまた、「切り出し」のみならず「行の抽出」も同時にできるということがわかってくる。
しかし行の抽出にしか使えないと思われていたgrepも、実は-oPをつければ、文字列の「切り出し」にも使えますよというお話でした。
WMPから読み込んだmp3ファイルのID3タグの文字化けが治らない理由
自宅サーバに音楽ファイルを入れて家の中からPCやiPadでアクセスして音楽を聴いているが、どうも昔Windows Media Playerでインポートしたmp3ファイルのメタ情報の文字化けが残ったままだった。
色々ググってみたところ文字化けをするのはmp3ファイルのメタ情報(ID3タグ)がShift-JIS(以下、SJIS)で保存されているのが原因らしい。併せてEasyTAGなるソフトウェアで治せるとの情報があり、試してみたが、結局直すことができなかった。
なぜ治せないのだろうか?と思い、mp3ファイルのメタ情報を16進数で出力してみたら、ちょっと気になった点があった。音楽のメタ情報についての知識は疎いので、これから話すことの理由についてよくご存じの方が居たら詳しく教えていただきたい。
私の音楽フォルダにある「葉加瀬太郎 - 情熱大陸.mp3」というファイルのタグ情報をmid3v2コマンドで表示するとこのようになる。ターミナルソフト上ではUTF-8以外のマルチバイト文字は文字化けするようになっているため、やはりID3タグ情報は文字化けしている。
例えばTALBの部分はおそらくアルバム名であろう。ここは本来は「情熱大陸」となっているはずである。
ここで下の画像のようにアルバム名の文字化け部分だけをシェルで切り出す。
確かになんとなく4文字ということはわかる。
od -xにより16進数表示をする。
8f c2 ae c3 94 c2 c2 4d c3 91 c2 a5 c2 97 0a a4
するとなぜか16バイト分の文字列が出現する。はて、SJISは2バイト文字ではなかっただろうか?なぜ8バイトではないのだろうか。
そこで試しに純粋なSJISの「情熱大陸」という文字列は、16進数で表すとどのようになるのかを、下記のコマンドで調べてみる。
ee 8f 4d 94 e5 91 a4 97 00 0a
すると、見事に8バイトである。つまりID3タグに含まれていた情報はSJISではなかったのか……?
ここで、ID3タグの文字列と、正規のSJISの文字列の16進数版を比較してみよう。
- ID3タグ内の「情熱大陸」という文字列の16進数表記
8f c2 ae c3 94 c2 c2 4d c3 91 c2 a5 c2 97 0a a4
- 純粋なShift-JISの「情熱大陸」の16進数表記
ee 8f 4d 94 e5 91 a4 97 00 0a
すると、どうも法則性があるような気がする。
ID3タグ情報は、本来ならば2バイト文字であるSJISの文字を、1バイトずつに分割し、c2、あるいはc3という1バイトを付与しているような気がする。しかし具体的な法則性を考察するのは面倒なのでやめる。
つまり、愚直に純粋なSJISからUnicodeへ変換しようとしていたEasyTAGでは、この文字化けは治せなかったということなのかもしれない。
このようなファイルに関してはMp3tagやID3Uniなどのソフトを使って文字化けを直すことができた(参考)が、果たしてこれらのソフトウェアはどのようにして文字エンコードを変換しているのだろうか?
試しにID3UniのREADMEを読んでみたが、やはりSJISからUnicodeへ変換するソフトであるという旨が書いてあった。正確にはコイツが変換している文字列はSJISとは似て非なるものなのだが……。
これは仮説だが、もしかしたら、.NET Frameworkなどを使用すると、フレームワークがメタ情報の扱い方を隠蔽化してしまっているのかもしれない。ゆえに、開発者はファイルからメタ情報を取り出したり、更新したりすることはできるが、実際に書き込まれているバイト列までは意識しなくて良い開発環境が整っているのかもしれない。
だがそもそもの話、なぜこのような似非SJISバイト列になっているのだろうか?SJISには2バイト目が5C等になりうることによる問題がある。それを防ぐための方策だろうか?
いずれにしても、Windows Media Playerで音楽を取り込むのは今後控えておこう……。
Cygwinのインストール方法+α
この記事では基本的なCygwin*1のインストール手順に加えて、とりあえず私が最初にやっておいた方が良いと思う下記の2点について説明する。
- apt-cygを使えるようにしておく
- カレントディレクトリでCygwinを開けるようにしておく
この記事の内容は、既に存在するCygwinのインストール手順について説明したサイトとほとんど同じである。
しかし、既存サイトは、大学の講義での使用を目的とした解説や、特定のソフトウェアの利用のみを目的としたものが散見され、必ずしも万人が使うとは限らないパッケージの導入について述べていることが多い。
そこで本記事は、私の知人たちを初めとした「特定の目的はないが、コマンドを使って日々のファイル・文字列操作を楽にしたい人」向けに説明するものである。
続きを読むHandBrakeCLIで品質を指定して動画を変換
DVDのISOイメージから、mp4へ動画を変換するのに、HandBrakeというソフトを使った。このソフトの良いところはHandBrakeCLIという、コンソール上で変換をするための実行ファイルも付属していることだ。このおかげで、UNIX系のコマンドを利用して、複雑に入り組んだディレクトリの中から、特定の条件に合致する動画ファイルを変換することができる。
HandBrakeCLI -i input.iso -o output.mp4
ちなみに動画の品質を指定して変換する場合は、--qualityオプションに続いて、品質を表す文字列を併記する必要がある。こんな感じに。
HandBrakeCLI --quality "RF:15" -i input.iso -o output.mp4
文字列は"RF:○○"という数字を含んだフォーマットに従う。15~35くらいのレンジで変化できて、数字が小さいほど高画質。品質の詳細は下記サイトにあった。 参考