OSX에서는 날짜 형식의 유효성을 검사한 다음 이를 에포크 시간으로 변환하는 함수를 구축하고 있습니다. 함수는 날짜가 다음 형식 중 하나인지 확인해야 합니다(오류가 없는 경우). 01/01/1970 10:00PM
또는 10:00PM
( %m/%d/%Y %I:%M%p
또는 %I:%M%p
)
기능
checkTIME () {
local CONVERT_CHK_TIME="$1"
if [[ "$CONVERT_CHK_TIME" =~ ^(0[0-9]|1[0-2]):[0-9][0-9](AM|PM)$ ]]; then
CONVERT_TIME="$(date -j -f "%I:%M%p" "$CONVERT_CHK_TIME" "+%s")"
elif [[ "$CONVERT_CHK_TIME" =~ (0[0-9]|1[0-2])\/([0-2][0-9]|3[0-1])\/\d{4}\s[0-9][0-9]:[0-9][0-9](AM|PM) ]]; then
CONVERT_TIME="$(date -j -f "%m/%d/%Y %I:%M%p" "$CONVERT_CHK_TIME" "+%s")"
else
echo "ERROR!"
exit 1
fi
}
현재는 잘 작동 10:00PM
하지만 시도하면 일치하지 않습니다.01/10/2017 10:00PM
나는 그것을 이렇게 부른다:
./convert '01/10/2017 10:00PM'
...
...
+ [[ -n 01/10/2017 10:00PM ]]
+ checkTIME '01/10/2017 10:00PM'
+ local 'CONVERT_CHK_TIME=01/10/2017 10:00PM'
+ [[ 01/10/2017 10:00PM =~ ^(0[0-9]|1[0-2]):[0-9][0-9](AM|PM)$ ]]
+ [[ 01/10/2017 10:00PM =~ (0[0-9]|1[0-2])/([0-2][0-9]|3[0-1])/d{4}s[0-9][0-9]:[0-9][0-9](AM|PM) ]]
+ echo 'ERROR!'
ERROR!
+ exit 1
감사해요!
또한 다음 정규식을 시도했습니다.
(0[0-9]|1[0-2])\/([0-2][0-9]|3[0-1])\/\d{4}\ [0-9][0-9]:[0-9][0-9](AM|PM)
답변1
GNU에 액세스할 수 있는 경우 한 가지 옵션 date
은 GNU가 무거운 작업을 수행하도록 하고 RE 복잡성을 완전히 방지하는 것입니다.
checkTIME () {
convert_time=$(date --date "$1" +'%s' 2>/dev/null)
if [[ -z "$convert_time" ]]
then
echo 'ERROR!'
exit 1
fi
}
GNU에 접근할 수 없으며 date
검증을 위해 RE match가 필요하다고 안내하셨으므로 이 방법을 사용하시면 됩니다. (나는 당신이 다른 여러 가지를 제공했다는 것을 알고 있습니다.)
[[ " $1 " =~ ^' '*([01]?[0-9]/[0123]?[0-9]/2[0-9][0-9][0-9])?' '+([01]?[0-9]:[0-5][0-9][AP]M)?' '*$ ]]
입력 매개변수( )의 양쪽에 추가 공백을 추가하여 $1
어떤 항목과도 일치시킬 수 있습니다.날짜,시간, 또는날짜 시간(두 구성요소 사이에는 필수 공백이 있습니다.) 작성된 대로 날짜 부분에는 2000년대의 4자리 연도가 필요합니다. 이 요구 사항을 완화해도 됩니다.
한 번은 ' '
공백을 지정했습니다. 원하는 경우 이를 사용하여 [[:space:]]
공백을 나타낼 수 있습니다.
비교 후 날짜 부분을 로 ${BASH_REMATCH[1]}
, 시간 부분을 으로 선택할 수 있습니다 ${BASH_REMATCH[2]}
.
답변2
\d
일부 버전의 정규식(perl)에서는 십진수 일치가 가능하지만 그렇지 않습니다.확장 정규식명령에 사용되는 =~
연산자 입니다.[[
bash
따라서 십진수 4자리와 일치하도록 패턴이 \d
변경 .[0-9]
마찬가지로 \s
리터럴 공백 문자를 일치시키려면 \s
이스케이프된 공백( \
)으로 바꾸십시오. 1개 이상 일치시키려는 경우공백(공백 또는 탭) \s
을 선택하고 [[:blank:]]+
.
더 중요한 것은 이러한 정규 표현식과의 혼동을 피하는 것입니다.
man bash
=~
다음을 기반으로 정규식을 나타냅니다 .확장 정규식에 설명된 대로 구문을 사용합니다 regex(3)
.
man 3 regex
(POSIX 정규식 함수)는 SEE ALSO regex(7)
.
man 7 regex
정규식 구문에 대한 설명을 제공하고 다음과 같이 말합니다 SEE ALSO POSIX.2, section 2.8 (Regular Expression Notation)
.
에서 전체 POSIX 확장 정규식 구문을 찾을 수 있습니다. 공개 그룹Posix 정규식 문서.
답변3
귀하의 bash 버전에서는 \d 및 \s 이스케이프가 작동하지 않는 것 같습니다. 대신 [[:digit:]]
and를 사용해 보세요 [[:space:]]
.
(0[0-9]|1[0-2])/([0-2][0-9]|3[0-1])/[[:digit:]]{4}[[:space:]](0[0-9]|1[0-2]):[0-9][0-9](AM|PM)
실행 중:
bash-3.2$ [[ "01/10/2017 10:00PM" =~ (0[0-9]|1[0-2])/([0-2][0-9]|3[0-1])/[[:digit:]]{4}[[:space:]](0[0-9]|1[0-2]):[0-9][0-9](AM|PM) ]] && echo match
match
답변4
파일 s1의 이 스니펫은 다음과 같습니다.
mydate='01/10/2017 10:00PM'
pl " Expected output:"
cat expected-output1
pl " Results:"
# Linux: dateutils.dconv -f "%s%n" -i "%m/%d/%Y %I:%M%p" "$mydate"
dateconv -f "%s%n" -i "%m/%d/%Y %I:%M%p" "$mydate"
생산하다:
-----
Expected output:
1484085600
-----
Results:
1484085600
이러한 시스템에서는:
OS, ker|rel, machine: Apple/BSD, Darwin 16.7.0, x86_64
Distribution : macOS 10.12.6 (16G29), Sierra
bash GNU bash 3.2.57
dateconv(일명 dconv, dateutils.dconv) 코드는 Brew를 통해 제공되는 dateutils 패키지의 일부입니다. dateconv에 대한 일부 세부정보는 다음과 같습니다.
dateconv - Convert DATE/TIMEs between calendrical systems.
Home : http://www.fresse.org/dateutils
Path : /usr/local/bin/dateconv
Version : - ( local: /usr/local/bin/dateconv, 2017-10-15 )
Type : Mach-O64-bitexecutablex86_64 ...)
행운을 빕니다... 건배, drl