특정 날짜가 포함된 파일이 있는데 이를 UTC 형식으로 변환하고 싶습니다. 그래서 작은 대본을 준비했어요
다음 오류가 발생합니다.
date: option requires an argument -- 'd'
Try `date --help' for more information.
date: extra operand `16:16:53'
내 파일 내용은 다음과 같습니다.
20191014161653042nmd
20191014161653052egc
20191004081901490egc
20191004081901493nex
20191004081901497nex
20191004081902531nex
20191004081902534ksd
내 코드는 다음과 같습니다
for i in $(cut -f1 Firstfile)
do
echo "$i" > tmpfile
TIME=$(awk '{print substr($1,1,14)}' tmpfile | sed -re 's/^([0-9]{8})([0-9]{2})([0-9]{2})([0-9]{2})$/\1\\ \2:\3:\4/' | xargs date +@%s -d | xargs date -u +"%Y-%m-%dT%H:%M:%S" -d)
MSec=$(awk '{print substr($1,15,3)}' tmpfile)
Msg=$(awk '{print substr($1,18,3)}' tmpfile)
echo -e "$TIME.$MSec $Msg" >> ResultFile
done
명령만 사용하면 제대로 작동하고 원하는 결과를 얻습니다.
awk '{print substr($1,1,14)}' tmpfile | sed -re 's/^([0-9]{8})([0-9]{2})([0-9]{2})([0-9]{2})$/\1\\ \2:\3:\4/' | xargs date +@%s -d | xargs date -u +"%Y-%m-%dT%H:%M:%S" -d
내가 대본에서 어떤 실수를 했나요? for 루프의 스크립트를 통해 전달할 때 왜 작동하지 않습니까?
예상되는 결과:
2019-10-14T20:16:52.042 nmd
2019-10-14T20:16:52.052 egc
2019-10-04T12:19:01.490 egc
등.
답변1
문제는 date
사용 하기에 너무 많은 데이터를 전달하고 있다는 것입니다 xargs
. 또한 출력의 일부로 만들기 위해 끝에 추가 텍스트 문자열을 전달하지 않는다는 것입니다.
awk
스크립트에서 모든 작업을 수행하는 것이 좋습니다 . GNU awk
와 mawk
GNU에는 모두 기본 타임스탬프 작업을 위한 기능이 있습니다.
{
YYYY = substr($1, 1, 4) # year
mm = substr($1, 5, 2) # month
dd = substr($1, 7, 2) # day
HH = substr($1, 9, 2) # hour
MM = substr($1, 11, 2) # minute
SS = substr($1, 13, 2) # seconds
sss = substr($1, 15, 3) # fractional seconds
text = substr($1, 18) # the rest
tm = mktime(sprintf("%s %s %s %s %s %s", YYYY, mm, dd, HH, MM, SS))
printf("%s.%s %s\n", strftime("%Y-%m-%dT%H:%M:%S", tm, 1), sss, text)
}
이는 입력 타임스탬프의 개별 구성 요소를 개별 변수로 선택하는 방법을 사용합니다 substr()
. 그런 다음 Unix 시간을 계산하고 mktime()
(입력 시간이 현지 시간대에 있다고 가정) 적절한 형식으로 변환된 (UTC) 타임스탬프 문자열을 사용합니다 strftime()
.
코드에서 초의 분수 부분은 sss
시간 계산의 일부가 아니지만 입력에서 출력으로 그대로 전송됩니다.
실행하세요:
$ awk -f script.awk file
2019-10-14T14:16:53.042 nmd
2019-10-14T14:16:53.052 egc
2019-10-04T06:19:01.490 egc
2019-10-04T06:19:01.493 nex
2019-10-04T06:19:01.497 nex
2019-10-04T06:19:02.531 nex
2019-10-04T06:19:02.534 ksd
mktime()
strftime()
설명서 의 설명서를 참조하십시오 awk
.
답변2
이것은 sed와 bash를 사용하는 버전입니다.
sed -re 's/^([0-9]{8})([0-9]{2})([0-9]{2})([0-9]{2})(([0-9]{3,}){0,1})([a-z].*)$/D="\1\ \2:\3:\4";M="\5";E="\7"/' /tmp/tmpfile |\
xargs -d'\n' -I=:= bash -c '(=:=;echo $(date -u +"%Y-%m-%dT%H:%M:%S.$M" -d "TZ=\"America/New_York\" $D" ) $E)'
sed 두 번째 부분의 모든 내용을 awk + sed
삭제 하지 않기 위해 sed 단계를 1개만 수행했습니다.\
xargs 옵션을 사용하여 -I
인수를 사용할 위치를 지정합니다 {}
.find
날짜를 두 번 사용하지 않기 위해 날짜 옵션 TZ
의 옵션을 사용합니다.-d
America/New_York
여기서는 시간대를 입력으로 사용하고 있으므로 이를 올바른 값으로 변경해야 합니다.