!["date -d @xxxxxx" 및 "find ./" 명령을 연결하는 방법은 무엇입니까?](https://linux55.com/image/72986/%22date%20-d%20%40xxxxxx%22%20%EB%B0%8F%20%22find%20.%2F%22%20%EB%AA%85%EB%A0%B9%EC%9D%84%20%EC%97%B0%EA%B2%B0%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
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
또는 xargs
2로 파이프해야 합니다.
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의 답변을 바탕으로
함parallel
xargs -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
및 특정 구문)은 루프 내에서 결과를 재사용하려는 경우에만 필요합니다 .zsh
bash
답변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, "." );