sed의 \1(또는 awk의 $1)을 어떻게 작동하나요?

sed의 \1(또는 awk의 $1)을 어떻게 작동하나요?

여러 줄이 포함된 파일이 있습니다. 각각에는 타임스탬프와 텍스트가 있습니다.

1534888050 some text
1534888051 some more text
1534888052 text

...텍스트를 보존하면서 타임스탬프를 읽을 수 있는 형식으로 변환하려고 합니다. 결과는 다음과 같습니다.

Tue Aug 21 21:47:30 UTC 2018 some text
Tue Aug 21 21:47:31 UTC 2018 some more text
Tue Aug 21 21:47:32 UTC 2018 text

date -d@"${somedate}"타임스탬프 자체를 올바르게 변환합니다.

이제 필터/파이프 명령을 통해 동일한 효과를 얻고 싶습니다.sed또는(또는 다른 일반적인 명령).

이것은 작동하지 않지만 대략 내가 생각하는 것을 설명합니다.

echo '1534888050 some text' | sed "s#^\([0-9]*\) .*#`date -d@\1`#g"

(이것은 \1일치하는 타임스탬프입니다)

이것을 우아하게 달성할 수 있는 방법이 있습니까?

답변1

이것날짜 도구소프트웨어 패키지는 이런 종류의 작업, 특히 dconv도구에 적합합니다. (Ubuntu 시스템에 설치하는 경우 이 명령을 로 사용할 수 있습니다 dateutils.dconv.)

예는 다음과 같습니다.

$ cat testfile.txt 
1534888050 some text
1534888051 some more text
1534888052 text
$ dateutils.dconv -i '%s' -f '%a %b %d %T %Y' -S <testfile.txt 
Tue Aug 21 21:47:30 2018 some text
Tue Aug 21 21:47:31 2018 some more text
Tue Aug 21 21:47:32 2018 text
$ dateutils.dconv -i '%s' -f '%F %T' -S <testfile.txt 
2018-08-21 21:47:30 some text
2018-08-21 21:47:31 some more text
2018-08-21 21:47:32 text
$ 

플래그는 -S도구가 "sed 모드"에서 실행되고 출력에 날짜가 아닌 텍스트를 포함하도록 지시하는 핵심입니다.

-i플래그는 입력 날짜 형식을 지정하고 이 -f플래그는 출력 날짜 형식을 지정합니다.

답변2

GNU awk(일명)가 있는 경우 gawk내장 strftime함수를 사용하여 에포크 시간을 원하는 형식으로 변환할 수 있습니다.

$ TZ=UTC gawk '{$1 = strftime("%a %b %d %H:%M:%S %Z %Y", $1)} 1' file
Tue Aug 21 21:47:30 UTC 2018 some text
Tue Aug 21 21:47:31 UTC 2018 some more text
Tue Aug 21 21:47:32 UTC 2018 text

POSIX모듈과 함께 Perl을 사용할 수도 있습니다 :

$ TZ=UTC perl -MPOSIX -alne '
    print join " ", strftime("%a %b %d %H:%M:%S %Z %Y", localtime shift @F), @F
  ' file
Tue Aug 21 21:47:30 UTC 2018 some text
Tue Aug 21 21:47:31 UTC 2018 some more text
Tue Aug 21 21:47:32 UTC 2018 text

GNU 구현에는 외부 명령 실행을 허용하는 수정자가 sed있지만 e전체 패턴 공간에서 작동하므로 실제로 사용하기가 다소 번거롭습니다.

답변3

awk를 사용하세요:

{
  "date -d @" $1 | getline $1
}
1

결과:

Tue, Aug 21, 2018  4:47:30 PM some text
Tue, Aug 21, 2018  4:47:31 PM some more text
Tue, Aug 21, 2018  4:47:32 PM text

답변4

당신이 깨달아야 할 것은 GNU sed전체 패턴 공간이 RHS의 명령 평가 결과로 대체된다는 것입니다 s///e. 따라서 이 동작을 수용하기 위해 echo + date다음과 같은 명령 조합을 사용합니다.

 sed -e  's/^\([1-9][0-9]*\)\(.*\)/echo "`date -d@\"\1\"`\2"/e'  input-file.txt

의 경우 Perl매우 간단하게 LHS의 일치 항목은 직관적으로 예상할 수 있듯이 RHS에서만 대체됩니다.

  perl -pe 's/(\d+)/qx(date -d@"$1") =~ s|\n||r/e'  input-file.txt 

관련 정보