bash LINUXで日付をDD-MM-YYYYからYYYY-MM-DD形式に変換する

bash LINUXで日付をDD-MM-YYYYからYYYY-MM-DD形式に変換する

想像する:

ファイルの日付値をデフォルトでDD-MM-YYYY形式の変数として抽出しています。システム日付からこの日付を減算する必要があります。両方の日付がDD-MM-YYYY形式の場合、減算結果は無効です。だから私はGoogleからいくつかの内容を読み、両方の日付をYYYY-MM-DD形式で指定することにしました。これにより、減算後に正しい値が提供されます。システム日付形式をYYYY-MM-DDとして正常に指定しましたが、ファイルから取得した日付をYYYY-MM-DD形式に変換する際に問題があります。

次の解決策は1桁の日付に適用されます。

$ date -d $(sed "s/-/\//g" <<< '9-2-1832') +%Y-%m-%d
Output : 1832-09-02

しかし、日付を次のように2桁に変換しようとすると、次のようになります。

$ date -d $(sed "s/-/\//g" <<< '19-07-2021') +%Y-%m-%d

私は出力を得る

Invalid date '19/07/2021'

どこ:

19 - is Date of a month
07 - is Month i.e. July in this case.
2021 - is Year

希望の出力は ->2021-07-19

私は日付バージョンがdate(GNU coreutils)8.22のRH Linuxで作業しています。

上記の問題に対する解決策を提供するのに役立ちます。

答え1

あなたの場合、awkおそらくより良いアプローチになります。

$ awk -F'-' '{printf("%04d-%02d-%02d\n",$3,$2,$1)}' <<< '19-07-2021'
2021-07-19

答え2

date入力形式を指定できるbusyboxに切り替えることができます。

$ date=19-7-2021
$ busybox date -D %d-%m-%Y -d "$date" +%F
2021-07-19

019-007-2021(たとえば、日付は許可されません。)

ast-open実装と同じですdate(RedHatシステムではすぐに動作する可能性はありません)。

$ date -p %d-%m-%Y -d "$date" +%F
2021-07-19

GNUシステムの代わりにBSDシステムを使用している場合は、次のようにします。

$ date -jf %d-%m-%Y -- "$date" +%F
2021-07-19

または、組み込み日付の解析と形式をそのままzsh使用するように切り替えることもできます。bash

$ zmodload zsh/datetime
$ strftime -rs t %d-%m-%Y $date && strftime %F $t
2021-07-19

(は標準および()APIstrftimeにアクセスできる組み込み関数です。strftime()strptime()-r

また、適切な分割演算子とaがあり、任意の順序で引数を受け入れることprintfができます(GNUを含むほとんど%n$...の実装printf()の構文を使用しprintf()ますが、printf組み込みbashまたはGNUprintfスタンドアロンユーティリティではありません)、先行数値に引数を変換しません。 0がある場合は、デフォルトの8進数として扱われます。

$ printf '%3$04d-%2$02d-%1$01d\n' ${(s[-])date}
2021-07-19

または匿名関数を使用してください。

$ (){ printf '%04d-%02d-%02d\n' $3 $2 $1; } ${(s[-])date}
2021-07-19

または、ここでは配列反転演算子を使用します。

$ printf '%04d-%02d-%02d\n' ${(s[-]Oa)date}
2021-07-19

答え3

形式がでハードコードされている場合は、式DD-YY-YYYY全体をハードコードして使用することもできます。部分文字列の抽出非常に迅速に再フォーマットしてください。

#!/bin/bash
dmy=$(date +%d-%m-%Y)
ymd="${dmy: -4}-${dmy:3:2}-${dmy:0:2}"
echo "$dmy -> $ymd"

形式が次の場合にD[D]-M[M]-YYYY使用できます。一般的な表現やや遅い再フォーマット:

#!/bin/bash
dmy="9-2-1932"
if [[ "$dmy" =~ ^([[:digit:]]+)-([[:digit:]]+)-([[:digit:]]+)$ ]] ; then
  ymd="${BASH_REMATCH[3]}-${BASH_REMATCH[2]}-${BASH_REMATCH[1]}"
fi
echo "$dmy -> $ymd"

次の形式をよりよく使用できますprintf:

dmy="9-02-2032"
if [[ "$dmy" =~ ^([[:digit:]]+)-([[:digit:]]+)-([[:digit:]]+)$ ]] ; then
  printf -v ymd '%.4d-%.2d-%.2d' \
    "${BASH_REMATCH[3]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}"
fi
echo "$dmy -> $ymd"

この回答の以前のバージョンは、私が完全に読んでいないことが判明し、次のYYYY-MM-DDように翻訳されましたDD-MM-YYYY

#!/bin/bash

ymd=$(date  +%Y-%m-%d)
dmy="${ymd: -2}-${ymd:5:2}-${ymd:0:4}"
echo "$ymd -> $dmy"

答え4

sedのみを使用する迅速で簡潔なソリューション:

echo 19-07-2021 | sed -E 's/^([0-9]{1,2})-([0-9]{1,2})-([0-9]{4})$/\3-\2-\1/'

関連情報