나는.csv파일에 다음이 포함됨
Data1|Data2|10/24/2017 8:10:00 AM
3열의 날짜 및 시간 형식을 다음과 같이 변경하고 싶습니다.
10/24/2017 8:10:00 AM
(12시간)부터 ( 20171024 08:10:00
24시간)까지.
-d를 사용하지 마십시오
답변1
순수한 awk 솔루션(포킹 명령 없음 date
):
awk -F'|' -vOFS='|' '
function fail() {
printf "Bad data at line %d: ", NR
print
next
}
{
if (split($3, date_time, " ") != 3) fail()
if (split(date_time[1], date, "/") != 3) fail()
if (split(date_time[2], time, ":") != 3) fail()
if (time[1] == 12) time[1] = 0
if (date_time[3] == "PM") time[1] += 12
$3 = sprintf("%.4d%.2d%.2d %.2d:%.2d:%.2d", date[3], date[1], date[2], time[1], time[2], time[3])
print
}'
-F'|'
입력 라인을 세로선$1
,$2
,$3
등으로 나눕니다.split($3, date_time, " ")
날짜/시간 필드를 날짜, 시간, AM/PM 표시기의 세 부분으로 나눕니다. 세 개의 블록이 없으면 오류 메시지가 표시되고 해당 라인을 건너뜁니다.split(date_time[1], date, "/")
날짜를 월, 일, 연도로 나눕니다.split(date_time[2], time, ":")
시간을 시, 분, 초로 나누세요.- 예를 들어, 24시간 기준으로 오전 12시 42분은 00:42입니다. 물론 PM은 12시간을 추가합니다.
sprintf
연도, 월, 일, 시, 분, 초를 다시 그룹화하고 필요한 경우 앞에 0을 추가합니다.$3
형식이 변경된 날짜/시간을 사용하여 입력 행을 재구성 하려면 이를 할당 한 다음 인쇄합니다.기능: 예를 들어 입력 필드가 3개 이상인 경우
Data1|Data2|10/24/2017 8:10:00 AM|Data4|Data5
스크립트는 이러한 추가 필드를 유지합니다.
용법: 몇 가지 작은 변경 사항:
- 위의 여러 줄 명령을 입력한 다음
}'
마지막 줄 끝(바로 뒤)에 처리하려는 파일 이름을 입력하세요. 물론*.csv
파일 이름 외에 또는 파일 이름 대신 와일드카드(예: )를 사용할 수 있습니다. - 위와 동일하지만 그 후에는 다음과 같이
}'
말하십시오.<
그리고 파일 이름. (이렇게 하면 한 번에 하나의 파일만 처리할 수 있습니다.) - 스크립트 파일을 만듭니다.
- 첫 번째 줄은 이어야 합니다
#!/bin/sh
. (또는 원하는 경우#!/bin/bash
또는 을 사용할 수 있습니다#!/usr/bin/env bash
. 이러한 다양한 "she-bang" 줄과 상대적인 장점 및 대응 기호의 차이점에 대한 논의는 이 질문의 범위를 벗어납니다. 검색하면 이 주제에 대한 많은 토론을 찾을 수 있습니다.) - 그런 다음 2번째 줄부터 위의 코드를 입력하세요.
- 마지막 줄 끝( 바로 뒤
}'
)에"$@"
(포함하다인용 부호). - 문서를 저장합니다. 우리는 당신이 이 스크립트를 호출한다고 가정합니다
gman
. - 유형
chmod +x gman
. - 유형
./gman
뒤에 파일 이름 및/또는 와일드카드 목록을 입력하거나<
그리고 파일 이름.
- 첫 번째 줄은 이어야 합니다
답변2
이를 수행하는 한 가지 방법은 다음과 같습니다( infile
CSV 파일이라고 가정).
#!/bin/bash
IFS='|'
while read data1 data2 datestr
do
newdatestr=$(date -d"$datestr" +"%Y%m%d %T")
printf "%s|%s|%s\n" "$data1" "$data2" "$newdatestr"
done < infile
답변3
그리고 AWK
:
아카이브를 저장하십시오 a.awk
.
BEGIN{
FS="|"
OFS = FS
}
{
"date -d '"$3"' +'%Y%m%d %T' " | getline l
$3 = l
print $0
}
csv 파일로 실행하세요.
awk -f a.awk file.csv
예를 들어 출력은 다음과 같습니다.
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 20:10:00
Data1|Data2|20171024 20:10:00
Data1|Data2|20171024 20:14:00
Data1|Data2|20171024 20:14:00
Data1|Data2|20171024 20:11:00
Data1|Data2|20171024 20:10:06
Data1|Data2|20171024 20:10:06
Data1|Data2|20171024 08:10:50
예로서:
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 PM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:14:00 PM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:11:00 PM
Data1|Data2|10/24/2017 8:10:06 PM
Data1|Data2|10/24/2017 8:10:00 PM
Data1|Data2|10/24/2017 8:10:50 AM
답변4
프로세스 대체는 GNU date
(그러나 는 아님 date -d
) 및 유사한 쉘을 사용하여 bash
이해됩니다 .
$ cat file
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 AM
$ paste -d '|' <( cut -d '|' -f -2 file ) <( date -f <( cut -d '|' -f 3 file ) +'%Y%m%d %T' )
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 08:10:00
지정된 파일에서 구분된 세 번째 열을 추출 date
하는 명령에서 날짜를 읽기 위해 호출됩니다 . 한 줄에 형식이 변경된 날짜를 하나씩 입력하고 출력합니다.cut
|
그런 다음 를 사용하여 처음 두 열과 함께 붙여넣습니다 paste
.
단점은 파일을 두 번 읽지만 date
한 번만 호출된다는 것입니다 -d
.