年と月の形式がありますが、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")
ゼロで満たされた1桁の月は、ある場所では問題になりますが、別の場所では動作すると思います。
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 と桁数を年として使用して計算します。次に、残りの文字列を特定の月数に加算し、1日を減算します。この計算は、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
これは連想配列として使用されます。