第121回 chmodのためのls -l
ls -lを実行すると
$ ls -l total 16 -rw-r--r-- 1 bingo_nakanishi staff 0 6 12 20:15 bar.txt -r-x------ 1 bingo_nakanishi staff 0 6 3 23:12 foo.txt -rwxr-xr-x 1 bingo_nakanishi staff 432 6 12 21:07 ls_n.pl -rwxr-xr-x 1 bingo_nakanishi staff 423 6 12 21:04 ls_n2.pl
こんな感じで、権限が rwx-のどれかで表現されるわけですが、
chmodに与えるときの引数は数字にしてやらないといけない。
chmod 755 hoge.txt
これじゃあ、コピペできないではないか!
ということで、権限を数字であらわしてくれるPerlを書いてみました。
ソース
#!/usr/bin/perl use strict; my $h = {'r'=>4, 'w'=>2, 'x'=>1}; my @ls = `ls -l`; print shift @ls; for(@ls){ my $rwx = (split / /, $_)[0]; my @tmp = split //, $rwx; my $pre = sub{ my $num = 0; for(@tmp[1..3]){ $num += $h->{$_} } $num; }->() . sub{ my $num = 0; for(@tmp[4..6]){ $num += $h->{$_} } $num; }->() . sub{ my $num = 0; for(@tmp[7..9]){ $num += $h->{$_} } $num; }->(); print $pre, $_; }
結果
$ ./ls_n.pl total 16 644-rw-r--r-- 1 bingo_nakanishi staff 0 6 12 20:15 bar.txt 500-r-x------ 1 bingo_nakanishi staff 0 6 3 23:12 foo.txt 755-rwxr-xr-x 1 bingo_nakanishi staff 432 6 12 21:07 ls_n.pl 755-rwxr-xr-x 1 bingo_nakanishi staff 423 6 12 21:04 ls_n2.pl
行の頭に数字で表示されました。
アルゴリズムの説明
-rw-r--r-- 1 bingo_nakanishi staff 0 6 12 20:15 bar.txt
の部分から まず、
-rw-r--r--
の部分を、 $rwxに代入。
$rwxを1文字ずつばらして、@tmpに代入。
$tmp[0]は、ファイルかディレクトリかを表す部分なので、そこは、見てはいけない。なので@tmp[1..3]と1からスタート。
各無名関数に、オーナー、グループ、その他の権限を計算してもらい、その結果を文字列として連結。
ん〜でも、これだと、ls -lにしか使えない.....
これだと ls -lにしか使えないのでパイプで渡してきたのに数字を付け加えるものも書いてみました。
ソース
#!/usr/bin/perl use strict; my $h = {'r'=>4, 'w'=>2, 'x'=>1}; while(<>){ my $rwx = q/(r|w|x|-)/ x 9; my $pre = ''; if($_ =~ /^.$rwx/){ $pre = sub{ my $num = 0; for my $q($1,$2,$3){ $num += $h->{$q}; } $num; }->() . sub{ my $num = 0; for my $q($4,$5,$6){ $num += $h->{$q}; } $num; }->() . sub{ my $num = 0; for my $q($7,$8,$9){ $num += $h->{$q}; } $num; }->(); } print $pre, $_; }
結果
$ ls -ltr | ./ls_n2.pl total 16 500-r-x------ 1 bingo_nakanishi staff 0 6 3 23:12 foo.txt 644-rw-r--r-- 1 bingo_nakanishi staff 0 6 12 20:15 bar.txt 755-rwxr-xr-x 1 bingo_nakanishi staff 423 6 12 21:04 ls_n2.pl 755-rwxr-xr-x 1 bingo_nakanishi staff 432 6 12 21:07 ls_n.pl
正規表現は、ほとんど書いた事がないので、
なにかもっとよい方法や、まずい点にお気づきになりましたら、
教えていただけるとうれしいです。
アルゴリズムの説明
先頭が任意の文字で、r|w|x|-の文字が9つ連続した場合は、各文字を$1〜$9に記憶(先頭の任意の文字は記憶しない)。
あとは、各無名関数に、オーナー、グループ、その他の権限を計算させ、文字として連結。
おまけ
ちなみに、
sub{ }->()
のところはなにも、無名関数を使わなくても
do{ }
でもよいですね。
my $pre = do{ my $num = 0; for(@tmp[1..3]){ $num += $h->{$_} } $num; } . do{ my $num = 0; for(@tmp[4..6]){ $num += $h->{$_} } $num; } . do{ my $num = 0; for(@tmp[7..9]){ $num += $h->{$_} } $num; };
こんな感じで。