%EB%A5%BC%20%EC%82%AC%EB%9E%8C%EC%9D%B4%20%EC%9D%BD%EC%9D%84%20%EC%88%98%20%EC%9E%88%EB%8A%94%20%EB%82%A0%EC%A7%9C%EB%A1%9C%20%EB%B3%80%ED%99%98%ED%95%A9%EB%8B%88%EB%8B%A4..png)
일반 텍스트 파일의 Unix Epoch(밀리초)를 일반 날짜로 변경하고 싶습니다. 나는 bash, sed, awk 또는 perl 솔루션을 허용합니다.
예시 파일1(13자리만 날짜임):
Foo bar 1397497040418 foo 1526 bar foobar, bar 1397497060518.
Bar, 1357407040418 foo 10 foobar.
나는 다음과 같은 출력을 원합니다.
Foo bar 2014-04-14 19:37:20 foo 1526 bar foobar, bar 2014-04-14 19:37:40.
Bar, 2013-01-05 18:30:40 foo 10 foobar.
내 시도가 실패했습니다:
sed -E "s/([0-9]{10})/date -d @\1/;e" file1
어떤 아이디어가 있나요?
감사해요.
답변1
입력 파일을 사용하십시오.
perl -MTime::Piece -pe '
s{ \b (\d{10}) \d{3}\b }
{ localtime($1)->strftime("%F %T") }xge
' file1
Foo bar 2014-04-14 13:37:20 foo 1526 bar foobar, bar 2014-04-14 13:37:40.
Bar, 2013-01-05 12:30:40 foo 10 foobar.
답변2
추가 숫자를 무시하고 날짜 변환을 처음 10자리로만 제한하기를 원한다고 가정하면(즉, 날짜가 수십만 년 후가 아님을 의미) GNU를 사용하여 date
다음과 같이 할 수 있습니다 perl
.
$ perl -pe 's/\b(\d{10})\d{3}\b/chomp($i=`date -d \@$1 "+%F %T"`);$i/eg' file1
Foo bar 2014-04-14 18:37:20 foo 1526 bar foobar, bar 2014-04-14 18:37:40.
Bar, 2013-01-05 17:30:40 foo 10 foobar.
글렌의 솔루션그러나 더 깨끗하고 이식성이 높으므로 Perl 모듈을 사용하는 것이 마음에 들지 않는다면 (그리고 그렇게 해서도 안 됩니다), 저는 제 것보다 이 모듈을 추천합니다.
귀하의 sed
시도에 관해서는결과명령의 경우 백틱 또는 를 사용해야 합니다 $(command)
. 이제 거의 다 왔습니다.
$ sed -E "s/([0-9]{10})/$(date -d @\1)/" file1
Foo bar Thu 01 Jan 1970 01:00:01 AM BST418 foo 1526 bar foobar, bar 1397497060518.
Bar, Thu 01 Jan 1970 01:00:01 AM BST418 foo 10 foobar.
물론 이것은 추가 숫자를 제거하지도 않고 13자리로만 제한하지도 않지만 필요한 것이 무엇인지 명확하게 지정하지 않았으므로 수정 방법을 모르겠습니다. 내 Perl 솔루션이 이를 처리하므로 제거하고 싶지 않으면 sed를 사용할 수 있습니다.
답변3
및 기능 과 awk
함께 GNU를 사용하십시오 . EPOCH 타임스탬프이기 때문에 주어진 행을 스캔하여 10개 이상의 숫자가 포함된 레코드를 식별하세요.match()
substr()
strftime()
이 레코드에서 처음 10자리만 추출하여 strftime()
함수에 전달하고 필요한 경우 날짜 형식을 적용합니다. 이 기능을 사용하여 원본 레코드를 새 타임스탬프로 교체합니다 sub()
.
awk '
{
for(col=1; col<=NF; col++) {
if ( match($col, /[[:digit:]]{10,}/) ) {
sub( substr($col, RSTART, RLENGTH),
strftime("%Y-%m-%d %H:%M:%S", substr($col, RSTART, RLENGTH-3) ) )
}
}
}1' file1
답변4
GNU awk 시간 함수의 경우 match() 및 단어 경계에 대한 세 번째 인수는 다음과 같습니다.
$ awk '{
while ( match($0,/(.*)\<([0-9]{10})[0-9]{3}\>(.*)/,a) ) {
$0 = a[1] strftime("%F %T",a[2]) a[3]
}
print
}' file
Foo bar 2014-04-14 12:37:20 foo 1526 bar foobar, bar 2014-04-14 12:37:40.
Bar, 2013-01-05 11:30:40 foo 10 foobar.