
Bashスクリプトには次の行があります。
while true; do
DATE=date
FORMAT="%Y%m%d"
read -p "Enter start date (YYYYMMDD) " STARTDATE
if date=$(date -d "$STARTDATE" +'+%Y%m%d'); then
start_date=`$DATE +$FORMAT -d $STARTDATE`
echo $start_date
break
fi
echo "Please use right format (YYYYMMDD) "
done
この方法は、入力が8つの数字である限り、うまく機能します(例:「20210901」を許可し、「20213131」を拒否)。ただし、入力が完全にオフになっている場合(例:「a」または「nonsense」)、今日の日付のみが必要です。型をより厳密に確認するには、コードをどのように変更する必要がありますか?
修正されたコードは次のとおりです。
valid=0
while true; do
DATE=date
FORMAT="%Y%m%d"
read -p "Enter start date (YYYYMMDD) " initialdate
if date=$(date -d "$initialdate" +'+%Y%m%d'); then
start_date=`$DATE +$FORMAT -d $initialdate`
if [[ "$start_date" =~ ^[[0123456789]]{8}$ ]]
then
valid=1
echo "valid";
echo $start_date
break
else
echo "Invalid format"
fi
fi
echo "Please use right format (YYYYMMDD) "
done
答え1
入力検証を実行する一般的な方法は、入力検証が終了したら中断できる無限ループを使用することです。
この場合、「検証済み」とは、入力文字列に8桁の数字しか含まれておらず、GNUがその日付をオプションのオプション引数date
として使用できることを意味します。-d
それで、bash
私たちは次のように書くことができます。
while true; do
read -r -p 'Input date: '
if [[ $REPLY =~ ^[[:digit:]]{8}$ ]] && date -d "$REPLY" >/dev/null 2>&1
then
break
fi
echo 'Invalid format, try again' >&2
done
thedate=$REPLY
これは、ループの先頭から日付を読み取り、文字列に8桁しか含まれていない場合は、一致する正規表現を使用してテストします。テストに合格すると、文字列もGNUを使用してテストされますdate
。すべてが順調に進むと、ループはbreak
ステートメントを介して終了します。
では、sh
正規表現の一致をシェルパターンの一致に置き換える必要があります。
while true; do
printf 'Input date: ' >&2
read -r REPLY
case $REPLY in
*[![:digit:]]*)
;;
????????)
date -d "$REPLY" >/dev/null 2>&1 && break
esac
echo 'Invalid format, try again' >&2
done
thedate=$REPLY
ここでテストは、まず文字列に数字以外の文字が含まれているかどうかをテストします。そのテストが失敗した場合、次のテストは正確に8文字です。テストが成功すると、GNUを使用してテストする8桁の文字列を取得し、date
日付が正しい場合はループを終了します。
答え2
入力に正確に8桁の数字を含める必要があるかどうかを確認する追加のチェックで、作業を減らし、Bashを使用しているため、正規表現比較演算子を利用できます。
if [[ "$startdate" =~ ^[0123456789]{8}$ ]]; then echo "valid"; else echo "invalid"; fi
これは、内容が$startdate
正確に8桁の数字で構成された正規表現と一致することを確認します。
次のように組み合わせることができます。
valid=0
while (( valid == 0 )); do
valid=1
IFS= read -r -p "Enter start date (YYYYMMDD): " startdate
if [[ ! "$startdate" =~ ^[0123456789]{8}$ ]]; then valid=0;
elif ! date -d "$startdate" +%Y%m%d > /dev/null 2>&1 ; then valid=0; fi
if (( valid == 0 )); then printf "Invalid date entered\n"; fi
done
# < ... operations for valid date here ... >
デフォルトのルールは次のとおりです。
- 推奨用途
shellcheck
また、シェルスクリプトを検証するために、多くのLinuxディストリビューションでスタンドアロンプログラムとしても使用できます。 $PATH
誤って重要な設定を上書きしないように、変数名を環境変数としてエクスポートする必要がない限り、変数名をすべて大文字にすることはお勧めできません。
答え3
または、無限ループなしでBSDdate(1)
コマンドを想定します。
REPLY=
valid=false
while ! $valid; do
read -r -p 'Input date: '
if ([[ $REPLY =~ ^[[:digit:]]{8}$ ]]) && (date -j +%Y%m%d ${REPLY}0000 >/dev/null 2>&1)
then
valid=true
else
echo 'Invalid format, try again' >&2
fi
done
thedate=$REPLY
BSDには完全なYmdHMが必要ですが、デフォルトのHMで十分であるため、この${REPLY}0000
構文が必要です。date
0000