연도와 월 형식이 있는데 YYMM
이를 형식으로 변환하고 싶습니다 YYYY Month
. 연도는 항상 2000년 이후입니다. 예를 들어;
1908
~이 되다2019 Aug
1904
~이 되다2019 Apr
2012
~이 되다2020 Dec
2111
~이 되다2021 Nov
나는 다음과 같이 스크립트를 작성했습니다.
rand=(1908 1904 2012 2001 2111)
months=(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
for i in $rand
do
echo ${i:2:2}
if [ ${i:2:2} -lt 1 ] || [ ${i:2:2} -gt 12 ]
then echo "Month: ${i:2:2}. Last 2 values must be a month between 01 and 12."
fi
printf "20${i:0:2} ${months[${i:2:2}]}"
done
그러나 몇 가지 오류가 발생합니다.
line 13: 08: value too great for base (error token is "08")
0으로 채워진 한 자리 월은 어떤 곳에서는 문제가 되지만 다른 곳에서는 작동한다고 생각합니다.
08
Bash가 이것이 단지 이라는 것을 이해하도록 하는 방법을 잘 모르겠습니다 . . 로 8
변경하려고 시도했지만 작동하지 않습니다.${i:2:2}
$((i:2:2))
line 7: i:2:2: syntax error in expression (error token is ":2:2")
답변1
08
잘못된 8진수로 해석됩니다. 0부터 시작하기 때문에 8진수이고 를 포함하고 있기 때문에 유효하지 않습니다 8
. 이는 산술 컨텍스트(정수 비교)에서 이 하위 문자열을 숫자로 사용하기 때문에 수행됩니다. 동일한 문제가 발생 09
하지만 숫자가 작을수록 문제가 발생하지 않습니다 07
.
YY
다음 스크립트는 날짜 2000-01-01과 자릿수를 연도로 사용하여 계산합니다. 그런 다음 나머지 문자열을 특정 월 수에 더하고 하루를 뺍니다. 이 계산은 YYMM
코드에 표시된 달의 마지막 날을 기준으로 합니다 . %Y %b
연도와 월을 형식으로 출력하는 데 사용합니다 YYYY Mon
.
#!/bin/bash
datecodes=(1908 1904 2012 2001 2111)
for datecode in "${datecodes[@]}"; do
printf -v thedate '2000-01-01 +%s years +%s months -1 day' "${datecode:0:2}" "${datecode:2}"
LC_ALL=C date -d "$thedate" +'%Y %b'
done
산출:
2019 Aug
2019 Apr
2020 Dec
2020 Jan
2021 Nov
GNU를 한 번만 호출하는 약간 더 효율적인 코드 date
:
#!/bin/bash
datecodes=(1908 1904 2012 2001 2111)
for datecode in "${datecodes[@]}"; do
printf '2000-01-01 +%s years +%s months -1 day\n' "${datecode:0:2}" "${datecode:2}"
done | LC_ALL=C date -f - +'%Y %b'
2013 Apr
이 코드를 사용하면 예를 들어 code 로 작성할 수 있습니다 1040
.
POSIX 로케일이 아닌 현재 로케일에 따라 형식화된 약식 월 이름을 얻으려면 에 LC_ALL=C
대한 이전 호출을 제거하십시오 date
.
GNU를 사용하지 않고 date
동일한 방법을 사용하여 날짜 코드의 월 부분을 확인하십시오.
#!/bin/bash
datecodes=(1908 1904 2012 2001 2111 1040)
declare -A months
months=(
[01]=Jan [02]=Feb [03]=Mar
[04]=Apr [05]=May [06]=Jun
[07]=Jul [08]=Aug [09]=Sep
[10]=Oct [11]=Nov [12]=Dec
)
for datecode in "${datecodes[@]}"; do
YY=${datecode:0:2}
MM=${datecode:2}
if [ -z "${months[$MM:-empty]}" ]; then
printf '"%s" is an invalid month\n' "$MM" >&2
continue
fi
printf '20%s %s\n' "$YY" "${months[$MM]}"
done
months
이는 연관 배열로 사용됩니다 .
답변2
이는 원하는 출력을 얻기 위해 위의 입력에 날짜를 추가하여 수행됩니다.
여기서는 유효한 입력의 입력에 언급된 구조에 날짜 "01"을 추가했습니다.
for i in 1908 1904 2012 2111; do date +%Y" "%b -d $i"01"; done
산출
2019 Aug
2019 Apr
2020 Dec
2021 Nov