映画『バクマン。』(2015)
頑張ってる人を見ると熱くなりますねえ。夢があって若くて友情で努力で勝利で最高です。何か自分も頑張りたくなります。絵でも描いてみようか。
ディレクトリをたくさん作って宝探ししてみます。
takk@deb8:~$ mkdir a;cd a
takk@deb8:~/a$ mkdir {1..9999}
takk@deb8:~/a$
ディレクトリを9999個用意したら、お宝をどこかのディレクトリにtouchで入れます。treasureというファイル名です。
takk@deb8:~/a$ touch `ls | sort -R | head -1`/treasure
このtreasureというファイルを見つけるのは、findを使えば簡単ですね。
takk@deb8:~/a$ find -name treasure ./7326/treasure takk@deb8:~/a$
では、少し複雑にします。木(tree)があるディレクトリの3番目に大きい数字の箱(box)にお宝が入っているものとします。
takk@deb8:~/a$ rm -rf *
takk@deb8:~/a$ mkdir {1..999}
##takk@deb8:~/a$ for i in `find -type d`;do touch $i/box{1..9};done
takk@deb8:~/a$ for i in `find -type d`;do for j in {1..10};do touch $i/box$RANDOM;done;done
takk@deb8:~/a$
takk@deb8:~/a$ a=`ls | sort -R | head -1`
takk@deb8:~/a$ touch $a/tree
takk@deb8:~/a$
さて、どう探しましょうか。
かなりfindを使い込んでいれば簡単でしょうけど、ベースのperlスクリプトがあれば、少し改造するだけで良いです。
find2perlを使って、findをperlスクリプトで実現してみましょう。
takk@deb8:~/a$ find2perl -name tree > hunter.pl takk@deb8:~/a$
hunter.plの内容です。
1 #! /usr/bin/perl -w
2 eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
3 if 0; #$running_under_some_shell
4
5 use strict;
6 use File::Find ();
7
8 # Set the variable $File::Find::dont_use_nlink if you're using AFS,
9 # since AFS cheats.
10
11 # for the convenience of &wanted calls, including -eval statements:
12 use vars qw/*name *dir *prune/;
13 *name = *File::Find::name;
14 *dir = *File::Find::dir;
15 *prune = *File::Find::prune;
16
17 sub wanted;
18
19
20
21 # Traverse desired filesystems
22 File::Find::find({wanted => \&wanted}, '.');
23 exit;
24
25
26 sub wanted {
27 /^tree\z/s
28 && print("$name\n");
29 }
30
26行目から29行目の内容を変えてやれば、findの条件が変更できます。
26 sub wanted {
27 if(/^tree\z/){
28 print "$dir\n";
29 system "ls \$dir | grep box | sort -tx -nrk2 | sed -n 3p";
30 }
31 }
実行すると該当するファイルが見つかります。
takk@deb8:~/a$ perl hunter.pl ./197 box26344 takk@deb8:~/a$
この結果はあってるでしょうか。確認してみます。
takk@deb8:~/a$ ls ./197/box* | sort -tx -nrk2 ./197/box32256 ./197/box32179 ./197/box26344 ./197/box17344 ./197/box15881 ./197/box15659 ./197/box14880 ./197/box8816 ./197/box7819 ./197/box4491 takk@deb8:~/a$ ls ./197/box* | sort -tx -nrk2 | sed -n 3p ./197/box26344 takk@deb8:~/a$
sortの-tオプションで指定しているxは、セパレータとしてboxのxの文字(数字の直前の文字)を指定しています。



コメント