더 중요한 것은 이러한 정규 표현식과의 혼동을 피하는 것입니다.

더 중요한 것은 이러한 정규 표현식과의 혼동을 피하는 것입니다.

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

관련 정보