2016年12月25日

vimを使ってファイル名を一括変更(リネーム)する

複数のファイル名を一括変更(リネーム)する時、どういった方法で行わているでしょうか?
専用のリネームツールを使うのも一つの手ですが、自分はもっぱらvimとコマンドプロンプトを使った方法で行っています。この方法のメリットとして、

  1. 普段使い慣れたvimコマンドで編集ができる
  2. リネーム操作を(ある程度)やり直すことができる
  3. Windowsに限らず、MacやLinuxでも似たような操作で実行できる

があげられます。
今回は、録画データのファイル名をリネームする方法を例に取って説明します。

リネーム元ファイルパスの取得

まず最初に、リネームしたいファイル一式が格納されているフォルダーをエクスプローラーで開きます。
そこでファイルを全て選択し、Shiftキーを押しながら右クリックを押すと、「パスのコピー」という項目が出てくるので、それを選択してファイルパスをクリップボードにコピーします。
次にvimを開いて、先ほどクリップボードにコピーしたファイルパスをエディター上に貼り付けます。
この際、場合によっては名前順に貼り付いていない事があるので、SHIFT+Vキーを押してこれら全てを行選択し、:sortと入力して選択範囲をソートしておきます。

フォルダーパスの除去(リネーム元ファイル名のみに編集)

貼り付けた文字列を見ると、行毎に両端がダブルクォーテーションでくくられており、ドライブ名から親フォルダーまでのフルパスが記載されています。
リネーム作業自体には影響ないのですが、事故防止のためControl+Vキーを押してドライブ名から親フォルダーまでの部分を矩形選択し、dキーを押して削除しておきます。
これで、ファイル名のみがダブルクォーテーションでくくられた状態になるはずです。
削除が不十分orし過ぎた場合は、慌てずuキーを押してアンドゥ(元に戻して)やり直します。

リネーム先ファイル名の準備

リネーム元ファイル名の準備ができたところで、今度はリネーム先ファイル名を準備します。
番組名には、タイトルや話数の他にサブタイトルなどの情報がありますが、それらをExcelなどの表形式であらかじめまとめておきます。もしくは、インターネット上に同じく表形式でまとまっている場合、それらをクリップボードにコピーしてvimに貼り付けます。
今回はWikipediaの源氏物語より、各帖と名前を話数とサブタイトルに見立ててリネーム先ファイル名とします。
上記表をブラウザーで開いたら、左端の列から右端まで13行分をマウスでドラッグして選択し、クリップボードにコピーしvimに貼り付けます。

リネーム先ファイル名の形式

貼り付けられた文字列をよく見ると、各項目がタブ文字<TAB>で区切られているかと思います。
このように、特定の区切り文字を挟んで行列(行方向は改行)の形になっている文字列を別の形に整形する場合は、正規表現のグループ化による一括置換が便利です。
なお、リネーム先ファイル名は、以下のフォーマットで整形します。

”タイトル<SP>第00話<SP>「サブタイトル」.mp4”
<SP>は半角スペース
00の部分は、話数の番号を2桁でゼロパディングしたもの
サブタイトルは、全角の括弧でくくられるようにする
末尾には拡張子.mp4を設定

リネーム先ファイル名の整形

では実際の整形作業を行ってみます。
まず、第1話~第9話の部分に矩形選択を使って"0"を挿入しておきます。
次に、話数とサブタイトルを行選択し、:キーを押した後に一括置換の正規表現パターンを入力します。

'<,'>s/^\(.\{-}\)<09>\(.\{-}\)<09>.*$/"リネームされた番組名 第\1話 「\2」.mp4"/

'<,'>の部分が「現在選択されている行」を表し、それに対して一括置換"s"をかける宣言を行い、置換元のパターンと置換先のパターンを"/"で区切って入力します。
置換元パターンに含まれるタブ文字<09>は、\tではなくControl+vキーを押した後にTABキーを押して制御文字として入力します。なお、\{-}は最短マッチ(.*?)になります。

リネームコマンドライン文字列の作成

ここまでできたら、リネーム先ファイル名をControl+vキーを押して矩形(ビジュアル)選択し、リネーム元ファイル名の右隣にペーストします。両端の間の空白はいくつあっても構いません。
最後に、先頭行にカーソルを移動してControl+vキーを押し、最下行までカーソルを移動したらShift+iキーを押して"ren "(スペース入力を忘れないこと)と入力し、リネームコマンドを完成させます。

リネームの実行

リネーム元ファイル名とリネーム先ファイル名が一致している事を確認できたら、いよいよリネームコマンドを実行します。
リネーム元ファイル名が格納されているフォルダーを右クリックすると、メニューに「コマンドウィンドウをここで開く」という項目が出てくるので、それを選択してコマンドプロンプトを開きます。
コマンドプロンプトが開いたら、リネーム元ファイルが存在することを確認し、先ほど作成したリネームコマンドライン文字列を貼り付けてリネーム処理を実行します。

リネームに失敗した場合

万が一リネームに失敗していた場合でも、コマンドに誤りがない限りはファイルが消えたりすることはありません。
念のため話数とファイル名が一致している事を確認し、リネーム作業を最初からやり直せばOKです。

2015年11月15日

実家に格安SIM+Rasberry Pi+NUC録画機を設置した話


半年以上前の話になるのですが、この前の実家への帰省の際に地元のTVやラジオをいつでも視聴できるよう設置してきました。
(上の写真はその時参加したサイクリング大会のやつです)

構成

  • Pocket WiFi LTE GL06P
    • インターネットへ接続するルーター
    • ヤフオクで買ったやつ
    • 電源はコンセントから常時供給しておく
  • OCNモバイルONE
    • ルーターに入れる格安SIM
    • この価格帯でグローバルIPが振られるSIMはこれしかなさそうだった
  • Intel DC3217BY
    • TVやラジオ視聴を処理するNUC
    • 地デジ録画(SKNet Monster TV HDUSを接続)
    • FMラジオ受信(RTL2832Uチップ搭載のUSBワンセグチューナーを接続)
    • リモートから電源を入れられる対応を実施済み
  • Raspberry Pi 1 Model B
  • TENVIS JPT3815W
    • ネットワークカメラ
    • 両親の様子を、、じゃなくて単純に外の風景を撮影
    • DDNS更新をONにしてRasPiがDNS更新に失敗した時のバックアップも


帰省前の準備


普段使いのサーバーとかであれば自分で赴いてメンテナンスできるのですが、実家に設置となると気軽にそういう事はできませんので、いろいろな対策を考える必要がありました。
  • 問題が起こった際の復帰手段と予防策
    • SSH -R(autossh)などで、こちらから接続できない場合の別ルートの確保
    • 定期的な死活監視と週次での自動再起動
  • 両親のPCリテラシーは高くないので、細かい操作は期待できない
    • 電話口で機器の様子を見てもらったり、電源入れ直してもらったりする程度
  • 実家に負担がかからないようにする
    • 通信費→帯域やレイテンシー的に固定回線を引きたいけど格安SIMで代替
    • 電気代→サーバーは常時起動ではなく必要な時のみ電源を入れる/落とせる
これらのうち、事前にプログラミングや工作が必要だったものは自宅で行い、最終的な動作テストののち帰省数日前に梱包して送付しました。気分的には火星探査機を開発している気分です(笑)

設置後のトラブル


準備段階で気をつけていたつもりだったのですが、やはり完璧とはいかずさまざまなトラブルに見舞われました。
  • 無線LANの設定が自宅の設定のままになっている
    • 実家を出る数時間前に発覚
    • 急いで近くの家電量販店にキーボードとHDMIケーブルを買いに行って修正
      • 最近のTVはPCモニター代わりになって便利
  • ネットワークカメラの設置場所が不安定
    • 窓を開ける取っ手が邪魔、高さが足りず撮影できない
    • ホームセンターで板切れを買って棚を作り対応
  • ルーターの電源が落ちる
    • 自宅に戻って設定をいじってたら突然接続断
    • 仕方ないので実家に電話して見てもらったら”充電中”になってた
      • 通信し続けると充電を中断してバッテリー駆動になる?
一番致命的なのは最後のルーター周りで、録画データは一括送信できないのでsplitコマンドで50MBくらいに分割し、cronで間欠的に送信するようにしました。おかげで1時間番組を録画してもこっちで視聴できるまでに3日ぐらいかかります。。

また、レイテンシーの遅さも予想以上で、通信の少なそうな深夜帯でも500msくらいかかるので、リアルタイムに視聴する系はほぼ諦めてます。。

あとトラブルというわけではないのですが、実家の両親に火事の心配をされました。確かに機器は常時電源接続されており、特にルーターはリチウムイオン電池も入っているのでその辺の配慮が足りなかったのは反省点です。

おわりに

いろいろ問題はありましたが、なんとか最低限の目標は達成できました。ネットワークカメラも当初は固定で一場面の撮影のみでしたが、パンチルトを操作するAPIを使って二場面を撮影できるようにし、温度/湿度センサーの値を画像に合成するようにしました。
(「なんかカメラが定期的に首振るんだけど!」と実家から電話がかかってきましたがw)

来年の帰省の際は、グローバルIPを諦めてもっと安いSIMに乗り換える(IIJ系SIMはIPv6が使えるらしいけど。。)、RasPi側に録画視聴を集約する(RasPi2化する)あたりを検討中です。最近IoTが話題ですが、それらを考えるきっかけとしてもオススメです。

2015年7月6日

BME280を使ってRaspberry Pi 2から温度/湿度/気圧を取得しようとした(できました)


以前挑戦してダメだったRaspberry Pi 2とBME280ですが、こちらの記事でセンサー情報取得プログラムにPython版が出たことを知り、合わせてI2C用プルアップ抵抗?の接続も不要のように見えたので、以前と同様にジャンパー線で直接接続する形にしてみました。

この方式だと3.3VとGNDを余計に消費してしまいますが、それ以外のセンサーを繋ぐ予定も無いため、とりあえずはこれで運用してみようと思います。