파일 수정의 월 2자리, 연도 2자리를 구하려고 하는데 작동하지 않습니다.
modified=$(stat -c %y "$line");
# modified="2018-08-22 14:39:36.400469308 -0400"
if [[ $modified =~ ".{2}(\d{2})-(\d{2})" ]]; then
echo ${BASH_REMATCH[0]}
echo ${BASH_REMATCH[1]
fi
내가 뭘 잘못했나요?
답변1
첫째, 따옴표는 정규 표현식에서 특수 문자의 의미를 억제합니다(온라인 매뉴얼):
추가 이진 연산자
=~
, ... 를 사용하여 패턴의 모든 부분을 인용하여 인용된 부분을 문자열로 일치시킬 수 있습니다. ...정규식 구문에서 특수 문자를 일치시키려면 해당 문자를 인용하여 특수 문자를 제거해야 합니다.
매뉴얼에서는 쉘 구문 분석과 정규식 구문 간의 충돌을 방지하기 위해 정규식을 변수에 넣을 것을 권장합니다.
둘째, \d
여러분이 생각하는 대로 작동하지 않고 단지 text 와 일치합니다 d
.
또한 ${BASH_REMATCH[0]}
인덱싱된 전체 일치 문자열 1
과 그 이상은 캡처된 그룹에 포함됩니다.
또한 다음과 같이 4자리 연도를 사용하는 것이 좋습니다.
modified=$(stat -c %y "$file")
re='^([0-9]{4})-([0-9]{2})'
if [[ $modified =~ $re ]]; then
echo "year: ${BASH_REMATCH[1]}"
echo "month: ${BASH_REMATCH[2]}"
else
echo "invalid timestamp"
fi
오늘 수정된 파일의 경우 year: 2018
및 month: 08
. 앞에 0이 있는 숫자는 쉘 및 기타 유틸리티에서 8진수로 처리됩니다.
(1900년대의 날짜를 처리해야 하는 경우 4자리 연도는 문제가 되지 않으며, 월 단위보다는 연도로 식별하기가 더 쉽습니다.)
답변2
이를 위해서는 정규 표현식이 필요하지 않습니다.
$ touch -t 197001010000 myfile
$ ls -l myfile
-rw-rw-r-- 1 jackman jackman 0 Jan 1 1970 myfile
$ IFS='-' read -r year month _rest < <(stat -c %y myfile)
$ echo "$year:${year#??}"$month"
1970:70:01
답변3
대안으로 GNU를 사용하여 date
다음을 수행할 수 있습니다.
eval "$(date -r "$file" +'year=%Y month=%-m day=%-d')"
수정 시간의 연도, 월, 일 부분을 및 각각에 저장하려면 $year
( $month
10 진수 정수로 앞에 0이 표시되는 경우 s를 제거하고 2 자리 연도 $day
참조 ).-
%-m
%-d
%y
(GNU와 달리 stat
심볼릭 링크 유형 파일의 경우 심볼릭 링크 자체의 수정 시간이 아니라 심볼릭 링크 대상의 수정 시간이 고려됩니다. GNU에서는 stat
이것을 사용할 수 있습니다 stat -L
).