Category perl.

rename コマンドで可能だぞ。rename コマンドは Perl の式でファイル名を置換可能だ!

「拡張子のないファイル」にマッチするシェルのglob表現は簡単ではないし、シェルスクリプトの for 文の文法はだいたいいつも忘れている。rename コマンドは Perl の正規表現という大変慣れたものを使え、sed や awk などと比べても安心感がある。

rename -v -n 's/^([^.]+)$/$1.txt/' *

置換が行われなかった場合リネームは行われない。-n はドライランなので実際に実行するときは外す。-v は verbose オプションで、つけておいたほうがいい。

この正規表現では . を含まないファイル名にマッチさせ、.txt をファイル名にあとに追加している。

備考

Ubuntu の wiki によると

UNIXにこのコマンドがないこともあって余り知られていませんが、どのLinuxにも含まれています。

https://wiki.ubuntulinux.jp/UbuntuTips/FileHandling/RenameCommand

らしいが、本当のところどうなのかよくわからないぞ! すくなくとも Ubuntu では使用可能だ! なお OS X には含まれていない。

OS X では brew install rename で入るが、これは Ubuntu のパッケージのものとはまた別のバージョンである。ただし高機能版であり、-v -n オプションは互換性がある (-n の longname は Ubuntu 版では no-act だが、homebrew で入るものは --dry-run または --just-print となっている)。

copyright

ライセンスはどちらも This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself. となっており Perl と同一 (Artistic License) のようだ。原版と同じ名称を使ってはいけないライセンスだった気がするが……

Ubuntu 版

# This script was developed by Robin Barker (Robin.Barker@npl.co.uk),
# from Larry Wall's original script eg/rename from the perl source.

homebrew 版

AUTHORS
Aristotle Pagaltzis

Idea, inspiration and original code from Larry Wall and Robin Barker.

となっており、Larry Wall (Original?) → Robin Barker (Ubuntu版) → Aristotle Pagaltzis (homebrew版) という感じで進化している雰囲気がある

  1. トップ
  2. tech
  3. 拡張子のないファイルに一括で拡張子を付与する
  1. トップ
  2. perl
  3. 拡張子のないファイルに一括で拡張子を付与する

ワーカー使っていると、一部のジョブだけちょっと優先的に実行したいということがあるので、TheSchwartz の場合、prioritize => 1 にしてプライオリティを有効にするとよいのですが、挙動でハマったのでメモをしておきます。

今回のケース

そもそもジョブごとにプライオリティはつけていないが、一部のジョブだけ手動対応で優先して処理を行いたくなった。

やったこと

該当ジョブを

update job set run_after = insert_time, grabbed_until = insert_time, priority = 1 where ...;

で優先順位を設定しすぐに実行開始できるようにした

結果

_人人人人人人人人人人人人_
> なかなか実行されない <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

というのも、TheSchwartz は priority 順でソートして50件取得して、それをシャッフルしてから1件選んで実行する、という挙動をするため。

つまり、優先順位を設定したとしても有象無象と混ぜられた 1/50 のクジに当たらなければ、そのジョブは実行されない。1/50 って2%だよ…… 2%…… 100回ジョブ実行しようとしてようやく86.7%の確率だよ……


どうするか?

とにかく入ってるジョブをすぐ実行したい場合

  • $TheSchwartz::FIND_JOB_BATCH_SIZE (デフォルト50) を 1 にする
  • 該当ジョブ以外の run_after を適当に未来に設定する
  • ジョブIDを指定して1回だけワークするスクリプト書いて手動実行

ぐらいしかない。

  1. トップ
  2. tech
  3. TheSchwartz の prioritize を有効にしたときの挙動は愉快
  1. トップ
  2. perl
  3. TheSchwartz の prioritize を有効にしたときの挙動は愉快

Locale::Maketext::Extract::Plugin 以下にはいろいろ対応してるフォーマットがあったりする。まぁ大抵一緒なので頑張って使う必要もないけど、これらを使って .po ファイルを作らないまでも、msgid の抽出だけ行いたいという場合があったりします。そんなときは直接 LME インスタンスを作って extract_file をかけて compile すれば、とれるようになるみたいです。

use Locale::Maketext::Extract;
use Locale::Maketext::Extract::Plugin::Xslate;
use File::Zglob;

my $lme = Locale::Maketext::Extract->new(
    plugins => {
        perl => [ 'pm' ],
        xslate  => {
            syntax     => 'TTerse',
            extensions => [qw/ tt /],
        },
        generic => [ 'js' ]
    },
    warnings => 1,
    verbose => 0,
);
 
 
for (zglob('lib/**/*.pm'), zglob('template/**/*.tt'), zglob('static/**/*.js')) {
    $lme->extract_file($_);
}

$lme->compile(1); # これをしないと msgids がとれない

for my $msgid ($lme->msgids) {
    say $msgid;
    $lme->msg_positions($msgid); # 見つかった場所がとれる
}
  1. トップ
  2. tech
  3. Locale::Maketext::Extract でスキャンだけする。
  1. トップ
  2. perl
  3. Locale::Maketext::Extract でスキャンだけする。