"date -d @xxxxxx" 및 "find ./" 명령을 연결하는 방법은 무엇입니까?

"date -d @xxxxxx" 및 "find ./" 명령을 연결하는 방법은 무엇입니까?

1970년 1월 1일 이후 이름이 밀리초 단위의 타임스탬프인 일부 디렉터리가 있습니다.

1439715011728
1439793321429
1439879712214
.
.

다음과 같은 출력이 필요합니다.

1442039711    Sat Sep 12 08:35:11 CEST 2015
1442134211    Sun Sep 13 10:50:11 CEST 2015
1442212521    Mon Sep 14 08:35:21 CEST 2015
.
.

다음 명령을 통해 모든 디렉터리를 나열할 수 있습니다.

find ./ -type d | cut -c 3-12

하지만 출력을 다음 명령에 넣을 수는 없으며 date -d @xxxxxx출력을 조작할 수도 없습니다.

어떻게 해야 하나요?

답변1

올바른 방향으로 가고 있습니다(더 간단한 해결 방법을 찾으려면 2~3개의 명령을 실행하세요. 아래 참조). 현재 디렉토리를 제거 *하는 대신 밀리초를 다소 단순화하는 1을 사용한 ./다음 결과를 GNU parallel또는 xargs2로 파이프해야 합니다.

find * -type d | cut -c 1-10 | parallel date --date=@{} +%c

얻기 위해

Sat 12 Sep 2015 08:35:11 CEST
Sun 13 Sep 2015 10:50:11 CEST
Mon 14 Sep 2015 08:35:21 CEST

귀하의 예에서와 같이 그 앞에 초 오프셋을 추가하십시오.

find * -type d | cut -c 1-10 | parallel 'echo "{} "  $(date --date=@{} +%c)'

또는:

find * -type d | cut -c 1-10 | xargs -I{} bash -c 'echo "{} "  $(date --date=@{} +%c)'

얻으려면 :

1442039711  Sat 12 Sep 2015 08:35:11 CEST
1442134211  Sun 13 Sep 2015 10:50:11 CEST
1442212521  Mon 14 Sep 2015 08:35:21 CEST

그러나 이렇게 하는 것이 더 간단합니다.

find * -type d -printf "@%.10f\n" | date -f - +'%s  %c'

그러면 동일한 요청 출력이 다시 제공됩니다.

사용의 단점은 *확장이 명령줄에 의해 제한된다는 점이지만, 타임스탬프 값을 기준으로 디렉터리를 정렬할 수 있다는 장점이 있습니다. 디렉토리 수가 문제인 경우 이것을 사용하십시오 -mindepth 1. 그러나 순서가 손실됩니다.

find ./ -mindepth 1 -type d -printf "@%.10f\n" | date -f - +'%s  %c'

sort필요에 따라 삽입하십시오.

find ./ -mindepth 1 -type d -printf "@%.10f\n" | sort | date -f - +'%s  %c'

1이는 귀하의 예와 같이 중첩된 하위 디렉터리가 없다고 가정합니다. ./ -mindepth 1*@hobbs 및 @don_crissti가 제안한 대로 여기에서 수행할 수 있는 ² 대신
² 를 사용할 수도 있습니다. 이는 더 장황합니다. ³s 파일 읽기 기능 사용에 대한 Gilles의 답변을 바탕으로parallelxargs -I{}date

답변2

루프의 각 파일에 대해 여러 명령을 실행하는 것을 피하겠습니다. 이미 GNUisms를 사용하고 있으므로:

find . ! -name . -prune -type d |
  awk '{t = substr($0, 3, 10); print t, strftime("%a %b %d %T %Z %Y", t)}'

두 개의 명령만 실행합니다. strftime()GNU에만 해당됩니다. 예: date -d.

답변3

넌 이미 가지고있다:

find ./ -type d | cut -c 3-12

이는 아마도 에포크 형식의 타임스탬프를 제공할 것입니다. 이제 while 루프를 추가하세요.

find ./ -type d | cut -c 3-12 | while read datestamp
do
    printf %s "$datestamp"
    date -d "@$datestamp"
done

그러나 일부 셸에서 이 구문은 하위 셸에서 while 루프를 가져옵니다. 즉, 거기에 변수를 설정하려고 하면 루프를 벗어나면 변수가 표시되지 않습니다. 이 문제를 해결하려면 상황을 약간 바꿔야 합니다.

while read datestamp
do
    printf %s "$datestamp"
    date -d "@$datestamp"
done < <(find ./ -type d | cut -c 3-12)

서브쉘에 배치되고 find메인 쉘에 while 루프를 유지합니다. 그러나 이 구문(AT&T ksh및 특정 구문)은 루프 내에서 결과를 재사용하려는 경우에만 필요합니다 .zshbash

답변4

내가 할 일 - 타임스탬프 목록을 입력합니다.

#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;

while ( my $ts = <DATA> ) { 
   chomp ( $ts );
   my $t = Time::Piece->new();
   print $t->epoch, " ", $t,"\n";
}

__DATA__
1442039711  
1442134211  
1442212521

이 출력은 다음과 같습니다.

1442039711 Sat Sep 12 07:35:11 2015
1442134211 Sun Sep 13 09:50:11 2015
1442212521 Mon Sep 14 07:35:21 2015

특정 출력 형식을 원할 경우 strftime다음과 같이 사용할 수 있습니다.

print $t->epoch, " ", $t->strftime("%Y-%m-%d %H:%M:%S"),"\n";

파이프의 라이너로 바꾸십시오.

 perl -MTime::Piece -nle '$t=Time::Piece->new($_); print $t->epoch, "  ", $t, "\n";'

File::Find그러나 대신 이 모듈을 사용하고 모든 작업을 Perl에서 수행하는 것이 좋습니다 . 자르기 전에 디렉토리 구조를 예시로 주시면 예를 들어드리겠습니다. 하지만 다음과 같이 보일 것입니다:

#!/usr/bin/env perl

use strict;
use warnings;
use Time::Piece;
use File::Find; 

sub print_timestamp_if_dir {
   #skip if 'current' item is not a directory. 
   next unless -d; 
   #extract timestamp (replicating your cut command - I think?)
   my ( $timestamp ) = m/.{3}(\d{9})/; #like cut -c 3-12;

   #parse date
   my $t = Time::Piece->new($timestamp);
   #print file full path, epoch time and formatted time; 
   print $File::Find::name, " ", $t->epoch, " ", $t->strftime("%Y-%m-%d %H:%M:%S"),"\n";
}

find ( \&print_timestamp_if_dir, "." ); 

관련 정보