
파일이 수정된 월 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
생각하는 대로 수행되지 않고 문자 그대로 일치합니다 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
및 $day
각각에 저장하려면(10진수 정수로, 앞에 오는 0을 신경쓰는 경우 -
s 를 제거 %-m
하고 2자리 연도도 참조).%-d
%y
(GNU와는 반대로 stat
, 심볼릭 링크 유형의 파일의 경우 심볼릭 링크 자체의 수정 시간이 아니라 심볼릭 링크 대상의 수정 시간이 고려됩니다. GNU에서는 를 stat
사용합니다 stat -L
).