SunOS 용 Linux에서`find` 명령에 대한 대안이 있습니까?


10

find리눅스 명령은에 비해 선택의 여지가 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 패키지를 설치하십시오 .
Kusalananda

답변:


21

Linux와는 아무런 관련이 없습니다. 이 -printf술어는 GNU 구현에 고유합니다 find. 리눅스는 OS가 아니라 많은 OS에서 발견되는 커널 일뿐입니다. 과거에 대부분의 OS가 GNU 사용자 영역을 사용 했었지만, 현재 Linux를 사용하는 대부분의 OS는 내장되어 있으며 기본 명령이 있습니다.

find리눅스 이전 의 GNU 명령은 대부분의 유닉스 계열 OS에 설치 될 수 있습니다. 리눅스가 나오기 전에 솔라리스 (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 엘리먼트 (AS 수정 시간을 포함하는 파일 메타 데이터를 검색하기 위해 $s[9])), 로컬 타임 존 (의 해석을 localtime())과 형식 그것 ( strftime()그 다음) print파일 이름과 함께들 ( $_루프 변수의 경우는 아무도에서 지정되지 않은 perl, 그리고 $!것과 같습니다 stderror(errno), 마지막 시스템 호출 실패에 대한 오류 텍스트).


GNU 사람들이 개선 사항을 구현하기 전에 기존 표준을 살펴 본다면 좋지 않습니까? 지정하는 형식을 사용하는 방법에 대한 표준이 이미이 ls유형의 출력에 목록 모드 사양 참조 pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html
schily

5
@schily, GNU find-printf선행의 POSIX.2 때문에 POSIX의 사람들은 여기에 비난한다. 또한 POSIX 사양은 2000 년대까지 공개되지 않았습니다. 나는 여전히 stat10 년이 지난 후 형식 명세에 대해 다르고 열등한 구문으로 GNU 사람들을 소개 한 것에 대해 책임을지고있다 .
Stéphane Chazelas

GNU find가 그 기능을 언제 추가했는지 언급 할 수 있습니까? Solaris pax는 1998 년부터이 목록 모드를 지원하므로 SUSv2에 도입 된 것 같습니다.
schily

1
자신의 bin 디렉토리에 gnu find를 설치하고 표준 디렉토리 이전에 검색 경로를 설정할 수도 있습니다.
피터-복원 모니카

@schily, 내가 가지고있는 GNU find의 가장 초기 버전은 1991 년부터 3.1이며, 이미 -printf (3.1은 % k 형식 지시문을 추가했습니다)를 가졌으며 변경 로그는 추가되었을 때 언급되지 않았을 것입니다. 변경 로그는 1987 년으로 돌아 간다
스테판 Chazelas가에게

0

접근하는 또 다른 방법은 find2perl스크립트를 사용하는 것입니다.이 스크립트는 find명령 의 하위 집합 을 해당 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;

내가 만든 두 개의 샘플 파일에서 출력은 동일합니다.

$ 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.