web-dev-qa-db-ja.com

2017-03-08T19:41:26Zの日付のみを解析するにはどうすればよいですか?

2017-03-08T19:41:26Zからの日付のみを解析しようとしています。

望ましい出力は2017-03-08です。

6
dhaval

POSIXシェルでTの前の部分を抽出するには:

_time=2017-03-08T19:41:26Z
utc_date=${time%T*} # as already said
_

または、Bourne互換または非POSIXシェルの場合:

_expr "$time" : '\(.*\)T'
_

ここで、_2017-03-08T19:41:26Z_はzulu time(UTCの別名)であり、正確な時刻を明確に指定していることに注意してください。

当時、ロンドンでは2017-03-08でしたが、バンコクでは2017-03-09(早朝)でした。

その時刻指定のlocal日付(UTC日付ではなく)を知りたい場合は、バンコクのユーザーが2017-03-09を取得し、ロンドンのユーザーが2017-03を取得します。 -08、いくつかのオプションがあります。

GNU date

_time=2017-03-08T19:41:26Z

date -d "$time" +%F
_

(GNUのように簡単に日付を指定すると、そのズールー形式をそのまま使用できます)

_ksh93_と同じ:

_printf '%(%F)T\n' "$time"
_

zshが組み込まれている場合:

_zmodload zsh/datetime
TZ=UTC0 strftime -rs unix_time %Y-%m-%dT%TZ $time &&
strftime %Y-%m-%d $unix_time
_

(GNU ones where strftime()/strptime() support it)のようなシステムでは_%Y-%m-%d_を_%F_に置き換えることができます)。

_busybox date_と同様:

_unix_time=$(date -u -D %Y-%m-%dT%TZ -d "$time" +%s)
date -d "@$unix_time" +%Y-%m-%d
_
29

cutの使用:

カット-ファイルの各行からセクションを削除

-d、--delimiter = DELIMフィールド区切り文字にTABの代わりにDELIMを使用します

-f、--fields = LISTこれらのフィールドのみを選択します。 -sオプションが指定されていない限り、区切り文字を含まない行も出力します

echo "2017-03-08T19:41:26Z" | cut -d T -f 1
12
sgargel

Bashでは、変数の パラメータ展開 でいくつかの演算を使用できます。

timestamp='2017-03-08T19:41:26Z'
date=${timestamp:0:10}          # pick 10 characters starting at position 0
date=${timestamp%T*}            # remove everything starting at the 'T'

${variable%pattern}は実際には標準のシェル言語の一部であり、dashのような単純なシェルでもサポートされています。)

もちろん、これらは単純な部分文字列操作です。日付を実際にparseしたい場合は、別のことを行う必要があります。フォーマットは固定幅であるため、部分文字列の展開はもちろんここでうまく適合します。ただし、値が有効であることを確認したい場合などがあります。

10
ilkkachu

Bash変数の置換でこれをカバーできます。

OLD="2017-03-08T19:41:26Z"
NEW=${OLD%T*}
echo $NEW
2017-03-08

$ {string%substring}-$ substringの最短一致を$ stringの後ろから削除します。詳細は 文字列の操作

6
steve

それで、すべての数字-ダッシュ番号-ダッシュ番号を見つけますか?これは、日付の直後に "T"がなくても、より長い文字列/行で機能します。

grep -o "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]"

または同等ですが、中かっこ「repeats/multiples」を使用すると少し短くなります

grep -o '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}'

例:

$ echo 2017-03-08T19:41:26Z | grep -o '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}'
2017-03-08

入力に他のダッシュがあまりない場合は、4文字、ダッシュ、2文字、ダッシュ、さらに2文字を検索できます。

$ echo 2017-03-08T19:41:26Z | grep -o '....-..-..'
2017-03-08
5
Xen2050

日付

GNU日付を使用できる場合、これはあなたが望むことをします:

$ d='2017-03-08T19:41:26Z'
$ date +'%F' -ud "$d"
2017-03-08

TZ(またはロケール)の値に関する問題を回避するには、-uオプションを使用します。

他の場所で日付値が必要な場合、ローカルTZの値はこのオプションで機能します。

$ date +'%F' -d "$d"
2017-03-08               # May change in some locales.

または、TZに特定の値を使用することを選択できます。

$ TZ=Asia/Kolkata date +'%F' -d "$d"
2017-03-09               # next day in India.

コルカタは古いカルクタの現在の名前であることに注意してください。

シェル

  1. bash は、値が整数(秒単位)の場合にのみ実行できます。

    $ printf '%(%F)T\n' $(date +'%s' -d "$d")
    2017-03-08
    

    ただし、bashはTZ(またはロケール)の値の影響を受けます。

    $ TZ=GGG+3 bash -c 'printf "%(%FT%T)T\n" $(date +"%s" -ud "$1")' sh "$d"
    2017-03-08T16:41:26Z
    

    上記のT16:に注意してください(19ではありません)。

  2. ksh は両方の変換を実行できます(秒と形式へ):

    ksh$ printf '%(%F)T\n' "$d"
    2017-03-08
    

    ただし、TZ(またはロケール)によって同様に影響を受けます。

    $ TZ=GGG-7 ksh93 -c 'printf "%(%FT%T)T\n" "$1"' sh "$d"
    2017-03-09T02:41:26
    

    09T02に注意してください(08T19ではない)

  3. busybox 入力(-D)のフォーマット(-d)の説明が必要です。

    $ busybox date -u -D '%Y-%m-%dT%TZ' -d "$d" +'%F'
    2017-03-08
    

    -uを使用すると、出力に対するTZの影響を回避できます。ただし、busybox日付の現在のバージョンは、TimeZone値(-0400)の解析をまだ実装していません。しかし、将来的には、-zは将来の保護になります。

ストリング

値が常に時間を示すTを持ち、常にZ(zulu時間)である場合、この文字列操作で十分です(zuluベースの日付を取得するため)。

$ echo " ${d%%T*}"
2017-03-08
4
Isaac

awkで文字列を解析する別の方法:

echo 2017-03-08T19:41:26Z | awk -F"T" '{print $1}'

またはsedを使用:

echo "2017-03-08T19:41:26Z" | sed -e "s/T.*$//g"
2
Zumo de Vidrio

grepまで'T'

echo 2017-03-08T19:41:26Z | grep -Eo "[^T]+" | head -1
1
MikeD

原油、ただし目的固有:echo $in_date | sed 's/T.*//g'

例えば:

in_date="2017-03-08T19:41:26Z"
echo $in_date | sed 's/T.*//g'
2017-03-08
0
Bloodysock

Perlを使用して日付文字列全体を解析し、希望どおりにフォーマットします。

#!/usr/#bin/env Perl
use strict;
use warnings;

use Time::Piece;

while ( <DATA> ) { 
    chomp; 
    print Time::Piece -> strptime ( $_, "%Y-%m-%dT%H:%M:%SZ")->strftime("%Y-%m-%d");
}

__DATA__
2017-03-08T19:41:26Z

そしてワンライナーとして:

Perl -MTime::Piece -lne 'print Time::Piece->strptime($_,"%Y-%m-%dT%H:%M:%SZ")->strftime("%Y-%m-%d")'
0
Sobrique