date -d를 사용하지 않고 csv 파일의 날짜 및 시간 형식 변경

date -d를 사용하지 않고 csv 파일의 날짜 및 시간 형식 변경

나는.csv파일에 다음이 포함됨

Data1|Data2|10/24/2017 8:10:00 AM

3열의 날짜 및 시간 형식을 다음과 같이 변경하고 싶습니다.

10/24/2017 8:10:00 AM(12시간)부터 ( 20171024 08:10:0024시간)까지.

-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

이를 수행하는 한 가지 방법은 다음과 같습니다( infileCSV 파일이라고 가정).

#!/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.

관련 정보