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番目の奴とか、やるか普通?