どの月の半分かを検出するUnixシェルプログラムです。毎月特定の日付(dom) -le 16

どの月の半分かを検出するUnixシェルプログラムです。毎月特定の日付(dom) -le 16

最終的な目標は、変数YYYYMMDDを設定することです。ここで、DDは2つの変数(01または16)のうちの1つです。

2つの値のいずれかで変数を作成しようとしています。

これが私が今まで持っているものですが、うまくいきません。

DYA=date +%d 
DYB=IF [["$DYA" -ge 16]]; then 16
else 01
fi
YR=2020
MO=03

FD="$YR$MO$DY"
ECHO "$FD"

答え1

bashバージョン 4.2 以降の使用:

#!/bin/bash

printf -v day '%(%e)T' -1

if [[ $day -lt 16 ]]; then
    # 1st half of the month
    day=01
else
    # 2nd half of the month
    day=16
fi

printf '%(%Y%m)T%s\n' -1 "$day"

最初は、printf今月の日付を10進数で変数に印刷しますday。これらのif文は、その値に制限されるか、01その16値によって制限されます。

最後に、printf現在の年と月を印刷してから、最後に01or文字列を追加します。16

-1呼び出しの引数は、フォーマットprintf文字%(...)T列が現在の時刻をフォーマットされたタイムスタンプとして使用するようにします(bash4.3以降を使用している場合、最初の呼び出しは暗黙的であるため、厳密には要求されません)。

よりコンパクトなバージョンbash

#!/bin/bash

printf -v day '%(%e)T' -1
printf '%(%Y%m)T%.2d\n' -1 "$(( (day < 16) ? 1 : 16 ))"

ここでは、公開関数を使用して算術拡張テストを実行します。三項演算子 ?:。 16より小さい1場合は$day結果は文字列、1616より大きい場合は結果は文字列です。算術拡張の結果は、ゼロで埋められた整数形式で指定され、現在の年と月の後に挿入されます。


あなたのコードに関して:

  • そして[[ ... ]]両側にスペースが必要であることに注意してください(まあ、コマンドターミネーターなので、スペースなしですぐに表示されることがあります)。[[]];
  • dateコマンドの出力を変数に入れるには、コマンド置換を使用しますday=$( date +%e )ifこれは、値を出力するものであれば、あなたのステートメントに当てはまります(ただしそうではありません)。
  • Unixコマンドは大文字と小文字を区別するので、ECHOおそらくecho
  • 時間形式の出力と%d。算術コンテキスト(文)でこれらの値を使用すると、値は次のように解釈されます。0131if01078進数値を入力すると、08合計エラーが発生します09(無効な8進数)。だから私は%eとの間にゼロ以外のパディングされた整数を取得するために使用します。131

最後のポイントについて:私も利用可能です

printf -v day '%(%d)T' -1

01との間にゼロパディング値を取得するには、31以下を使用する必要があります。

if [[ 10#$day -ge 16 ]]; then

シェルが文字列を8進整数の代わりに10進整数として解釈するように強制します。


/bin/shスクリプトとして(bash4.2以前のバージョンでも動作します(例:bashmacOSのデフォルトシェル):

#!/bin/sh

day=$( date +%e )

if [ "$day" -lt 16 ]; then
    # 1st half of the month
    day=01
else
    # 2nd half of the month
    day=16
fi

date +"%Y%m$day"

標準シェルにはフォーマット文字列がshないため、日付文字列形式を使用する必要があります。代わりにテストにも使用されます(そして変数は二重引用符で囲む必要があります)。%(...)Tbashdate[ ... ][[ ... ]]

よりコンパクトなバージョン/bin/sh

#!/bin/sh

day=$( date +%e )
printf '%s%.2d\n' "$(date +%Y%m)" "$(( (day < 16) ? 1 : 16 ))"

このよりコンパクトなバージョンは、コンパクトなbash変形から派生しました。唯一の違いは、date現在の年と月の形式を指定することです。

答え2

上記を達成するには、次のコードを使用できます。 #touch mycode.sh

#!/bin/bash

export DD=$(date +%d)
export YYYY=$(date | awk '{print $6}')
export MM=$(date +%m)
echo "$YYYY$MM$DD"
if [[ $DD -eq 16 || $DD -eq 01  ]];then

 echo "$DD"

else

 echo " The days are not 1st or 16th "

fi


#sh mycode.sh

出力/出力

20200303

答え3

上記の作業は次のとおりです。作業コードは次のとおりです。

export day=$(date +%d)
export YR=$(date | awk '{print $6}')
export MM=$(date +%m)
echo $DY
echo "$YR$MM$day"

if [[ $day -ge 16 ]]; then
    day=16
else
day=01
fi
printf '%(%Y%m)T%s\n' -1 "$day"



export FD="$YR$MM$day"
echo $FD

答え4

dd=$(date +%d)
# values 08 and 09 will not work with arithmetic the way you expect
d=${dd#0}         # remove any leading 0
if [ "$d" -ge 16 ] ;then
  half=16
else
  half=01
fi
date "+%Y%m$half"

このコードが最も理解しやすいと思います。唯一の問題は、シェル算術式とdigitalで始まる数字を使用することです0。これは、以前に触れたことがなければ、おそらく気付かないでしょう。フォーマット文字列はマンページdateに記載されています。 (または)実装はstrftime(3)変換仕様を理解していません。設定は(または他のシェル)マンページの「パラメータ拡張」セクションに文書化されています。dateprintf%e${dd#0}bash(1)

関連情報