‘date -d @xxxxxx’및 ‘find ./’명령을 연결하는 방법은 무엇입니까? 디렉토리가 있습니다. 1439715011728 1439793321429 1439879712214 . . 그리고 다음과 같은 출력이 필요합니다. 1442039711

1970-01-01 이후 밀리 초 단위로 이름이 타임 스탬프 인 디렉토리가 있습니다.

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조작 할 수 없습니다 .

어떻게해야합니까?



답변

올바른 길을 가고 있습니다 (2 ~ 3 개의 명령 만 실행하는 간단한 솔루션은 아래 참조). 당신은 현재 디렉토리를 제거하기 위해 *대신에 사용해야 합니다 ./¹ 이것은 밀리 초의 절단을 약간 단순화 한 다음 결과를 GNU parallel또는 xargs² 로 파이프하면됩니다 :

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'

¹ 여기에서는 예제와 같이 중첩 된 하위 디렉토리가 없다고 가정합니다. 당신은 또한 사용할 수 있습니다 ./ -mindepth 1대신*
² 당신은 대체 할 수 parallel와 함께 xargs -I{}그것은 단지 더 자세한, @hobbs로 여기 @don_crissti은 제안했다.
³ 파일 읽기 기능 을 사용하는 Gilles의 답변을 기반으로 함date


답변

루프에서 파일 당 여러 명령을 실행하지 마십시오. 이미 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입니다.


답변

넌 이미 가지고있다:

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, zsh그리고 bash당신은하지만, 루프 내부에서 그 결과를 다시 사용하고자하는 경우 특정는)에만 필요합니다.


답변

GNU 날짜가있는 경우 입력 파일에서 읽은 날짜를 변환 할 수 있습니다. 타임 스탬프를 조금만 마사지하면 인식 할 수 있습니다. 유닉스 시대를 기반으로 한 타임 스탬프의 입력 구문 @은 소수점을 포함 할 수있는 초 수입니다.

find ./ -type d ! -name '*[!0-9]*' |
sed -e 's~.*/~@~' -e 's~[0-9][0-9][0-9]$~.&~' |
date -f - +'%s  %c'


답변

타임 스탬프 목록을 피드로 제공합니다.

#!/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모듈 을 사용하고 대신 펄에서 모든 일을하는 것이 좋습니다. 자르기 전에 디렉토리 구조의 예를 제시하면 예를 들어 보겠습니다. 그러나 다음과 같습니다.

#!/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, "." ); 


답변

zsh의 strftime의 내장 :

zmodload zsh/datetime
for d (*(/))
strftime '%s %a %b %d %T %Z %Y' $d

이것은 현재 디렉토리의 모든 디렉토리 이름이 실제로 획기적인 시간이라고 가정합니다.
예제에서 해당 숫자를 처리하는 방법을 명확히하면 추가 필터링 / 처리가 가능합니다 (Leia와 Luke Skywalker의 생년월일에 해당하는 에포크 시간과 유사 함). 예를 들어 최소한 일치하는 디렉토리 이름을 재귀 적으로 검색합니다. 10 자리 숫자를 입력하고 처음 10 자리를 기준으로 날짜를 계산하십시오.

setopt extendedglob
zmodload zsh/datetime
for d (**/[0-9](#c10,)(/))
strftime '%s %a %b %d %T %Z %Y' ${${d:t}:0:10}


답변

GNU Parallel 사용하기 :

find ./ -type d | cut -c 3-12 | parallel -k 'echo {} `date -d @{}`'

공백 대신 \ t를 사용할 수있는 경우 :

find ./ -type d | cut -c 3-12 | parallel -k --tag date -d @{}