Geekなぺーじ:10のUNIX小技にperlを加えるとさらに幸せになれるというお話。
1.ディレクトリの作成
今時-pをサポートしていないmkdir(1)はないと思いますが、ない場合は
perl -MFile::Path -e 'mkpath $_ for @ARGV' path/to/dir more/path/to/dir ...
で代用が出来ます。
alias mkpath perl -MFile::Path -e \'mkpath \$_ for @ARGV\'
と.bashrcや.cshrcとしておけば、
mkpath path/to/dir more/path/to/dir ...
と出来ます。
2. tarの解凍先を指定する
応用編として、ディレクトリーの中身を丸ごとコピーする場合にもtarが使えます。
tar cf - . | (cd dest && tar xpf -)
cp(1)などを使った場合、symlinkが実ファイルに置き換えられたり、ownershipやpermissionが変わってしまうことがありますが、これだとメタデータも確実に転写されます。
7. xargsをfind以外と組み合わせる
xargsの代わりに、perlのone-linerと組み合わせる方法もあります。
例:.htmをすべて.htmlに変更find . -type f -name \*.htm | perl -nle 'rename $_, $_ . "l"'
-nleを-pleにすると、ファイル名も一行ごとに表示されるようになります。
さらに、findまでperlにやらせるという方法もあります。
find * -type f -name \*.htm
の代わりに
find2perl . -type f -name \*.htm
とすると、
#! /usr/local/bin/perl -w
eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
if 0; #$running_under_some_shell
use strict;
use File::Find ();
# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.
# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
sub wanted;
# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, '.');
exit;
sub wanted {
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
-f _ &&
/^.*\.htm\z/s
&& print("$name\n");
}
という具合にfind(1)互換のperl scriptが標準出力されるので、これを
find2perl . -type f -name \*.htm > whatever.pl
としておいて、あとはwhatever.plを編集します。といっても実際に編集するのは、wanted()の中身だけ。通常のfind(1)ではやりにくい条件分岐なども、ここで簡単に行うことが出来ます。
9. パターンマッチは行全体ではなくフィールドで
perlだと、-aオプションを指定する事でawkっぽい振る舞いをさせることが出来ます。ただしフィールド変数は$数字ではなく、$F[数字]となります。
ls -l | perl -anle 'print if $F[6] eq "Dec"'
Enjoy!
Dan the Perl Monger
10番目の奴とか、やるか普通?