LinuxでSunOSの `find`コマンドに代わるものはありますか?


10

findLinux のコマンドには、findSunOSまたはSolarisのコマンドと比較して、多くのオプションがあります。

find次のようなコマンドを使用したい:

find data/ -type f -name "temp*" -printf "%TY-%Tm-%Td %f\n" | sort -r

Linuxマシンでは完全に正常に動作します-printfが、SunOSマシンでは同じコマンドにオプションがありません。出力を"%TY-%Tm-%Td %f\n"フォーマットでカスタマイズしたい。

SunOSの代替案を提案してください。


5
findSolarisでGNUを使用するには、findutilsパッケージをインストールします。
クサラナンダ

回答:


21

Linuxとは何の関係もないことに注意してください。この-printf述語は、GNUの実装に固有ですfind。LinuxはOSではなく、多くのOSにあるカーネルにすぎません。これらのOSのほとんどは過去にGNUユーザーランドを使用していましたが、現在Linuxを使用するOSの大多数は埋め込まれており、基本的なコマンドがあればそれを持っています。

findLinuxより前のGNU コマンドは、ほとんどの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。そしてperllstat()それぞれのonを実行して、ファイルのメタデータ(変更時刻を10番目の要素($s[9])として含む)を取得し、それをローカルタイムゾーン(localtime())で解釈してフォーマットし(strftime()print、ファイル名と並べます($_ループ変数の場合はどれも中に指定されていないperl、と$!の同等でstderror(errno)、最後のシステムコールの失敗のエラーテキスト)。


機能強化を実装する前に、GNUの人々が既存の標準を調べていたらいいのではないでしょうか。フォーマットを使用してlsタイプ出力を指定する方法に関する標準はすでにあります。pubs.opengroup.org
onlinepubs /

5
@schily、GNU find-printf以前からのPOSIX.2ので、POSIXの人々はここに非難しています。また、POSIX仕様は2000年代まで公開されていなかったことにも注意してください。stat10年以上後に、GNUの人々がその形式仕様の異なる劣った構文を導入したことを非難します。
ステファンChazelas

GNU findがその機能を追加したのはいつですか?Solaris paxは1998年以来このリストモードをサポートしているので、SUSv2で導入されたと思います。
schily

1
自分のbinディレクトリにgnu findをインストールして、正規ディレクトリの前に検索するパスを設定することもできます。
ピーター-モニカを

@schily、私が持っているGNU findの最も古いバージョンは1991年の3.1で、すでに-printf(3.1は%kフォーマットディレクティブが追加されました)がありました。変更ログはいつ追加されたかについては言及していません。ChangeLogは1987
StéphaneChazelas

0

これにアプローチするもう1つの方法は、find2perlスクリプトを使用することです。このスクリプトは、findコマンドの(ここではサブセット)を対応するperlスクリプトに変換します。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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.