![sed의 \1(또는 awk의 $1)을 어떻게 작동하나요?](https://linux55.com/image/139011/sed%EC%9D%98%20%5C1(%EB%98%90%EB%8A%94%20awk%EC%9D%98%20%241)%EC%9D%84%20%EC%96%B4%EB%96%BB%EA%B2%8C%20%EC%9E%91%EB%8F%99%ED%95%98%EB%82%98%EC%9A%94%3F.png)
여러 줄이 포함된 파일이 있습니다. 각각에는 타임스탬프와 텍스트가 있습니다.
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