想像する
私のコンテナの最後の配布日は次の形式です。
月/日/年または2024年2月11日。
最終配布日の出力方法を変更することはできません。
現在の日付から最後の配布日を引いた後、最後の配布日が2ヶ月以上経過した場合は、ファイルに書きたいと思います。
たとえば、コンテナ1 - 最後 - deploy.txt:
last deployed: jan/01/2024
これらのファイルはいくつかあります。
問題は、月が文字で提供されることです。正規表現を使用して日付を取得できます。
私が考えた1つの解決策は、次のように月を事前に置くことです。
dict=(
['jan']=1
['feb']=2
)
しかし、もっと良い方法があるでしょう。
アルファベットの月を整数に変換できますか?
これはmacOSのbash用であり、bash 3ソリューションが望ましいです。
答え1
MacOS date
- 日付文字列をエポックから秒に変換する
date
このコマンドは、libc関数を介して文字列形式の月を理解できますstrptime(3)
。私はmacosがないので答えをテストすることはできませんが、macosによるとdate
男性ページ:
date [-jRu] -f input_fmt new_date [+output_fmt]
[...]
-f Use input_fmt as the format string to parse the new_date provided rather than using the
default [[[mm]dd]HH]MM[[cc]yy][.ss] format. Parsing is done using strptime(3).
これで、マニュアルページで入力日をフォーマットする方法を知ることができます。strptime(3)
:
%b or %B or %h
The month name according to the current locale, in abbreviated
form or the full name.
%d or %e
The day of month (1-31).
%Y The year, including century (for example, 1991).
したがって、これによれば、入力形式は次のようになります"%b/%e/%Y"
。
次に、次のフラグを使用する必要がありますdate
。
-j Do not try to set the date. This allows you to use the -f flag in addition to the + option
to convert one date format to another. Note that any date or time components unspecified
by the -f format string take their values from the current time.
最後に、結果から現在時刻を減算できるようにしたいので、+出力_fmtする:
%s The number of seconds since the Epoch, 1970-01-01 00:00:00
+0000 (UTC). Leap seconds are not counted unless leap
second support is available.
したがって、日付形式をepochに変換する結果コマンドは次のようになります。
$ DATE="jan/01/2024"
$ date -jf "%b/%e/%Y" $DATE +%s
1704060000
繰り返しますが、Macosがないため、これを確認するためにテストすることはできません。また、小文字の月を許可するかどうかはわかりませんが、月を大文字に置き換える必要がある場合は、次のよう$DATE
に置き換えることができます。${DATE^}
完全性のために、次のコマンドを使用して同じことを行う方法も示します。
GNU date
- 日付文字列をエポックから秒に変換する
date
GNUバージョンはより多くの自由を提供するので、より簡単です。
それから男性ページ:
The --date=STRING is a mostly free format human readable date
string such as "Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29
16:21:42" or even "next Thursday". A date string may contain
items indicating calendar date, time of day, time zone, day of
week, relative time, relative date, and numbers. An empty string
indicates the beginning of the day. The date string format is
more complex than is easily documented here but is fully
described in the info documentation.
date
したがって、マイコンピュータでテストした結果、コマンドが理解できるように入力からスラッシュを削除する必要があります。
$ DATE="jan/01/2024"
$ echo ${DATE//\// }
jan 01 2024
$ date --date "${DATE//\// }" +%s
1704060000
現在の日付から減算
これで、元の日付の新起源時間を持つようになりました。ただ変数に保存するだけです。たとえば、MacOSでは次のようになります。
$ ORIG_DATE=$(date -jf "%b/%e/%Y" $DATE +%s)
エポック以降の現在の日付を秒単位で表示するには、次の手順を実行します。
$ date +%s
1704965965
違いを秒単位で計算する方法は簡単です。
$ echo $(( $(date +%s ) - $ORIG_DATE ))
905967
答え2
正確な要件を取得しようとする必要があります(おそらく要件がありますが、ここに記載されていない可能性があります)。
一つは、月の略語であると仮定されるロケールです。たとえば、ドイツ語のロケールでは、月名は英語のみのアプリケーションで印刷された日付を解析するときに問題を引き起こす可能性があります(例:
may
ismai
やoct
is in Germanokt
)。使用されている月の名前が現在のロケールと一致する場合は、デプロイ
date -d "$(echo jan/01/2024 | tr / ' ')"
日を簡単に解析できます。もう一つの質問は、日付の違いを計算する方法です。
日数(約60日)を計算するには、
+%s
formatパラメーターを使用して配布日と現在の日付を秒に変換し、その数値を引いた後に結果が60 * 86400より大きいことを確認します。もっと複雑なルール(例:月別の日付の比較)に従いたい場合は、まだbashで実行できますが、より難しくなります。
答え3
anydate
とanyを使用すると、awk
説明したように実行されます。
$ awk -v now="$(date +%m/%Y)" -v dif=2 -F'[ /]' '
BEGIN {
split(now,n)
now = n[1] + (n[2] * 12)
}
{
mth = ( index("janfebmaraprmayjunjulaugsepoctnovdec",$3) + 2 ) / 3
cur = mth + ($5 * 12)
}
(now - cur) > dif
' file
last deployed: oct/01/2023
上記のコードはこの入力ファイルで実行されます。
$ cat file
last deployed: oct/01/2023
last deployed: nov/01/2023
last deployed: dec/01/2023
last deployed: jan/01/2024
入力の月名が、Jan
またはのようにすべて小文字でない場合は、JAN
スクリプトからに$3
変更するだけです。tolower($3)
答え4
使用幸せ(以前のPerl_6)
まず、日付を有効な日付に変換します。ISO 8601日付:
~$ raku -pe 'BEGIN my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12; \
s{ ^ .+? <( ( <.alpha>**3 ) (\/) (\d**1..2) (\/) (\d**4) } = "$4-{sprintf q[%02d], %months{$0.tclc}}-$2".Date;' file
last deployed: 2024-01-01
心配しないでください。いつでも再フォーマットできます。
~$ raku -pe 'BEGIN my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12; \
s{ ^ .+? <( ( <.alpha>**3 ) (\/) (\d**1..2) (\/) (\d**4) } = "$4-{sprintf q[%02d], %months{$0.tclc}}-$2".Date.mm-dd-yyyy("/");' file
last deployed: 01/01/2024
この楽要素は今楽だからな日付オブジェクトに対して数学的計算を実行できます。
~$ raku -pe 'BEGIN my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12; \
s{ ^ .+? <( ( <.alpha>**3 ) (\/) (\d**1..2) (\/) (\d**4) } = Date.new(now) - "$4-{sprintf q[%02d], %months{$0.tclc}}-$2".Date ~ " days ago";' file
last deployed: 46 days ago
より多くのコード例については、以下のリンクを参照してください。
https://docs.raku.org/言語/temporal.html
https://github.com/Raku/examples/tree/master/categories/cookbook/03dates-and-times
https://raku.org