첫 번째 열에 날짜/시간을 나타내는 문자열이 있는 CSV가 있습니다. 추가 열을 추가하고 날짜/시간을 에포크로 변환하고 싶습니다.
나는 다음을 시도했다:
awk -F "," 'BEGIN{ OFS="," } {$14=$(date -jf "%m/%d/%Y %H:%M:%S %p" $1 "+%s"); print}’ mycsv.csv > test
나는 얻다:
awk: illegal field $(0%m/%d/%Y %H:%M:%S %p"1/30/2017 11:14:55 AM"+%s), name "(null)"
input record number 1, file mycsv.csv
source line number 1
이 필드에 대한 날짜 변환이 작동한다는 것을 알고 있으므로 일부 구문 오류가 발생합니다.
내가 원하는 것을 어떻게 할 수 있나요?
답변1
나는 GNU를 가지고 있기 date
때문에 명령줄 옵션이 다릅니다. 하지만 문제는 awk의 구문인 것 같습니다. $(...)
awk 스크립트에서는 쉘 하위 프로세스 구성을 사용할 수 없습니다 . system()
문자열을 전달하는 함수가 필요합니다 . 따라서 유효한 쉘 명령을 awk 문자열로 구성해야 하며, 이를 awk 스크립트 내에서 시스템에 전달할 수 있습니다.
이 같은:
awk -F "," 'BEGIN{ OFS="," } {$14=system("date -jf \"%m/%d/%Y %H:%M:%S %p\" \""$1"\" \"+%s\""); print}' mycsv.csv > test
또는 더 나은 가독성을 위해
awk -F "," '
BEGIN{ OFS="," }
{
$14 = system("date -jf \"%m/%d/%Y %H:%M:%S %p\" \"" $1 "\" \"+%s\"");
print
}' \
mycsv.csv > test
답변2
awk
GNU (내 생각에는 OSX에서 작동해야 한다고 생각함 ) 가 있는 경우 system 에 의존하는 대신 brew
내부 GNU를 사용할 수 있습니다 .mktime
strftime
date
안타깝게도 입력 형식이 다음 형식이 아닙니다.날짜 사양원하는 형식 mktime
이므로 시간 문자열을 일부 분할하고 재배열해야 합니다. 예를 들어, 주어진
$ cat file.csv
09/23/2016 11:12:19 AM,field2,field3
그 다음에
gawk -F, '
{
split($1,a,/[/: ]/);
ts = sprintf("%4d %02d %02d %2d %2d %2d", a[3], a[2], a[1], a[7] ~ /^[Pp]/ ? a[4]+12 : a[4], a[5], a[6]);
$0 = strftime("%s", mktime(ts)) FS $0
} 1' file.csv
1510243939,09/23/2016 11:12:19 AM,field2,field3
답변3
Miller( mlr
macOS에서 Homebrew를 통해 패키지로 사용 가능 miller
)를 사용하고 입력이 헤더 없는 CSV 파일이고 필드 1의 형식화된 날짜를 구문 분석하여 필드 14에 Unix 타임스탬프를 쓰려고 한다고 가정합니다.
mlr --csv -N put '$14 = strptime($1,"%m/%d/%Y %H:%M:%S %p")' mycsv.csv
헤더가 있는 경우 해당 -N
옵션을 제거하고 숫자 필드 대신 명명된 필드를 사용하십시오(예: ) $timestamp = strptime($date, ...)
.
이 strptime()
함수는 제공된 패턴을 사용하여 형식화된 날짜를 구문 분석하고 Unix 타임스탬프를 반환합니다.
질문에 언급된 날짜의 경우 UTC 시간대에 있다고 가정하면 새 필드의 값은 입니다 1485774895.000000
. 현지 시간대를 고려하려면 strptime_local()
대신 를 사용하세요 strptime()
. Unix 타임스탬프의 정수 부분만 필요한 경우 호출 strptime()
을 int(...)
.