IT Share you

Bash에서 날짜 구문 분석

shareyou 2021. 1. 10. 19:22
반응형

Bash에서 날짜 구문 분석


별도의 필드 (년, 월, 일, 시간, 분, 초)를 사용하여 bash에서 날짜를 다른 변수로 어떻게 구문 분석합니까?

날짜 형식은 다음과 같습니다. YYYY-MM-DD hh:mm:ss


bash 여야합니까? /bin/date여러 변환에 GNU coreutils 바이너리를 사용할 수 있습니다 .

 $ date --date="2009-01-02 03:04:05" "+%d %B of %Y at %H:%M and %S seconds"
 02 January of 2009 at 03:04 and 05 seconds

이것은 주어진 날짜를 구문 분석하고 선택한 형식으로 표시합니다. 필요에 따라 원하는대로 조정할 수 있습니다.


이것은 간단합니다. 대시와 콜론을 공백으로 변환하고 (IFS를 변경할 필요가 없음) 한 줄에 모두 '읽기'를 사용하면됩니다.

read Y M D h m s <<< ${date//[-:]/ }

예를 들면 :

$ date=$(date +'%Y-%m-%d %H:%M:%S')
$ read Y M D h m s <<< ${date//[-: ]/ }
$ echo "Y=$Y, m=$m"
Y=2009, m=57

입력 시간 형식이 다르므로 여기에 더 유연한 솔루션이 있습니다.

BSD / macOS에서 날짜 변환

date -jf in_format [+out_format] in_date

여기서 형식은 strftime을 사용합니다 (참조 man strftime).

주어진 입력 형식의 경우 YYYY-MM-DD hh:mm:ss:

$ date -jf '%Y-%m-%d %H:%M:%S' '2017-05-10 13:40:01'
Wed May 10 13:40:01 PDT 2017

그것들을 별도의 변수로 읽기 위해 NVRAM의 아이디어를 취하고 있지만 strftime 형식을 사용할 수 있습니다.

$ date_in='2017-05-10 13:40:01'

$ format='%Y-%m-%d %H:%M:%S'

$ read -r y m d H M S <<< "$(date -jf "$format" '+%Y %m %d %H %M %S' "$date_in")"

$ for var in y m d H M S; do echo "$var=${!var}"; done
y=2017
m=05
d=10
H=13
M=40
S=01

스크립트에서 항상 사용합니다 read -r.

제 경우에는 시간대간에 변환하고 싶었습니다 ( /usr/share/zoneinfo영역 이름 디렉토리 참조 ).

$ format=%Y-%m-%dT%H:%M:%S%z

$ TZ=UTC date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-10T00:40:01+0000

$ TZ=America/Los_Angeles date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-09T17:40:01-0700

GNU / Linux에서 날짜 변환

Mac에서는의 GNU 버전을 설치할 수 있습니다 dategdate와를 brew install coreutils.

date [+out_format] -d in_date

out_format은 strftime을 사용합니다 (참조 man strftime).

GNU coreutils의 date명령에서는 입력 형식을 스스로 알아 내려고 시도하기 때문에 입력 형식을 명시 적으로 설정할 수있는 방법이 없습니다. (자세한 내용은 coreutils : 날짜 입력 형식 에서 매뉴얼을 읽을 수 있습니다 .)

예를 들면 :

$ date '+%Y %m %d %H %M %S' -d '2017-05-10 13:40:01'
2017 05 10 13 40 01

별도의 변수로 읽으려면 괄호 안의 명령을 GNU 버전으로 바꾸어 Mac 섹션의 명령을 수정하십시오.

시간대간에 변환하려면 ( /usr/share/zoneinfo영역 이름에 대한 디렉토리 참조 ) TZ="America/Los_Angeles"입력 문자열에 바로 지정할 수 있습니다 . "영역 이름 주변 의 리터럴 문자와 in_date 앞의 공백 문자에 유의하십시오.

TZ=out_tz date [+out_format] 'TZ="in_tz" 'in_date

예를 들면 :

$ format='%Y-%m-%d %H:%M:%S%z'

$ TZ=America/Los_Angeles date +"$format" -d 'TZ="UTC" 2017-05-10 02:40:01'
2017-05-09 19:40:01-0700

$ TZ=UTC date +"$format" -d 'TZ="America/Los_Angeles" 2017-05-09 19:40:01'
2017-05-10 02:40:01+0000

GNU 날짜는 시간대의 시간 오프셋도 이해합니다.

$ TZ=UTC date +"$format" -d '2017-05-09 19:40:01-0700'
2017-05-10 02:40:01+0000

$ t='2009-12-03 12:38:15'
$ a=(`echo $t | sed -e 's/[:-]/ /g'`)
$ echo ${a[*]}
2009 12 03 12 38 15
$ echo ${a[3]}
12

배열 방법이 더 좋을 수도 있지만 이것이 특별히 요청한 것입니다.

IFS=" :-"
read year month day hour minute second < <(echo "YYYY-MM-DD hh:mm:ss")

순수한 배쉬 :

date="2009-12-03 15:35:11"
saveIFS="$IFS"
IFS="- :"
date=($date)
IFS="$saveIFS"
for field in "${date[@]}"
do
    echo $field
done

2009
12
03
15
35
11

셸 스크립팅을 사용하는 대신 필요에 따라 아래와 같이 스크립팅 자체에 통합하십시오.

a=date +%Y 
b=date +%S
c=date +%H

a는 연도 b는 초, c는 시간입니다. 등등.


OP 문제에 대한 또 다른 해결책 :

IFS=' -:' read y m d h m s<<<'2014-03-26 16:36:41'

BSD date및 GNU 를 사용하여 날짜를 다른 형식으로 변환 date:

$ LC_ALL=C date -jf '%a %b %e %H:%M:%S %Z %Y' 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
$ gdate -d 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41

GNU는 date인식 WedMar도 비 영어 로케일을하지만 BSD는 date하지 않습니다.

Converting seconds since epoch to a date and time with GNU date and BSD date:

$ gdate -d @1234567890 '+%F %T'
2009-02-14 01:31:30
$ date -r 1234567890 '+%F %T'
2009-02-14 01:31:30

Converting seconds to hours, minutes, and seconds with a POSIX shell, POSIX awk, GNU date, and BSD date:

$ s=12345;printf '%02d:%02d:%02d\n' $((s/3600)) $((s%3600/60)) $((s%60))
05:25:45
$ echo 12345|awk '{printf "%02d:%02d:%02d\n",$0/3600,$0%3600/60,$0%60}'
05:25:45
$ gdate -d @12345 +%T
05:25:45
$ date -r 12345 +%T
05:25:45

Converting seconds to days, hours, minutes, and seconds:

$ t=12345678
$ printf '%d:%02d:%02d:%02d\n' $((t/86400)) $((t/3600%24)) $((t/60%60)) $((t%60))
142:21:21:18

another pure bash

$ d="2009-12-03 15:35:11"
$ d=${d//[- :]/|}
$ IFS="|"
$ set -- $d
$ echo $1
2009
$ echo $2
12
$ echo $@
2009 12 03 15 35 11

have you tried using cut? something like this: dayofweek=date|cut -d" " -f1

ReferenceURL : https://stackoverflow.com/questions/1842634/parse-date-in-bash

반응형