Linuxのfind
コマンドには、SunOSまたはSolarisのfind
コマンドと比較して多くのオプションがあります。
次のようにfind
コマンドを使用したい:
find data/ -type f -name "temp*" -printf "%TY-%Tm-%Td %f\n" | sort -r
Linuxマシンでは問題なく動作しますが、SunOSマシンでは同じコマンドに-printf
オプションがありません。出力を"%TY-%Tm-%Td %f\n"
形式でカスタマイズしたい。
SunOSの代替案を提案してください。
Linuxとは何の関係もないことに注意してください。その_-printf
_述語は、GNU find
の実装に固有です。LinuxはOSではなく、多くのOSで見られるカーネルにすぎません。これらのOSのほとんどは、 a GNU以前はユーザーランドでしたが、今ではLinuxを使用するOSの大部分が組み込まれており、基本的なコマンドがあればそれを持っています。
Linuxより前のGNU find
コマンドは、ほとんどのUnixライクなOSにインストールできます。Linuxが登場する前は、Solaris(当時はSunOSと呼ばれていました)で確かに使用されていました。
現在では、Solaris用のOracleパッケージとしても利用できます。 Solaris 11では_file/gnu-findutils
_にあり、コマンドの名前はgfind
です(GNU find
の場合、システム独自のfind
コマンドと区別するため)。
ここで、パッケージをインストールできない場合は、おそらくPerl
を使用することをお勧めします。
_find data/ -type f -name "temp*" -exec Perl -MPOSIX -le '
for (@ARGV) {
unless(@s = lstat($_)) {
warn "$_: $!\n";
next;
}
print strftime("%Y-%m-%d", localtime($s[9])) . " $_";
}' {} + | sort -r
_
ここでは、find
(Solaris実装)を使用してファイルを検索していますが、_-exec
_述語を使用してファイルのリストをPerl
に渡します。そして、Perl
は、それぞれのlstat()
を実行して、ファイルのメタデータ(変更時刻を10番目の要素(_$s[9]
_)として含む)を取得し、ローカルタイムゾーンで解釈します(localtime()
)そしてそれをフォーマットします(strftime()
)これをファイル名と一緒にprint
s(_$_
_はPerl
で何も指定されていない場合ループ変数であり、_$!
_はstderror(errno)
、最後のシステムコールエラーのエラーテキスト)。
これに取り組む別の方法は、find
コマンドの(ここではサブセット)を対応するPerlスクリプトに変換するfind2Perl
スクリプトを使用することです。 PerlスクリプトはFile::Find
モジュールを使用して重い作業を行います。私のシステムのfind2Perlスクリプトは-printf
述語をサポートしていなかったため、手動で追加しました:
#! /usr/bin/Perl -w
use strict;
use File::Find ();
use vars qw/*name *dir *Prune/;
*name = *File::Find::name;
*dir = *File::Find::dir;
*Prune = *File::Find::Prune;
sub wanted {
my ($dev,$ino,$mode,$nlink,$uid,$gid, $mtime, $year, $month, $day);
if ((($dev,$ino,$mode,$nlink,$uid,$gid,undef,undef,undef,$mtime) = lstat($_)) &&
-f _ &&
/^temp.*\z/s) {
(undef, undef, undef, $day, $month, $year) = localtime($mtime);
$year += 1900;
$month++;
printf "%d-%d-%d %s\n", $year, $month, $day, $_;
}
}
File::Find::find({wanted => \&wanted}, 'data/');
exit;
私が作成した2つのサンプルファイルでは、出力は同じです。
$ tree data
data
├── subdir
│ └── foo
│ └── temp2
└── temp1
2 directories, 2 files
$ touch -d 2018-06-20 data/subdir/foo/temp2
$ touch -d 2018-05-19 data/temp1
$ find data/ -type f -name "temp*" -printf "%TY-%Tm-%Td %f\n" | sort -r
2018-06-20 temp2
2018-05-19 temp1
$ ./perlfind | sort -r
2018-06-20 temp2
2018-05-19 temp1