第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; };

こんな感じで。