Làm cách nào để phân tích ngày trong bash, với các trường riêng biệt (năm, tháng, ngày, giờ, phút, giây) thành các biến khác nhau?Ngày phân tích cú pháp trong Bash
Định dạng ngày là: YYYY-MM-DD hh:mm:ss
Làm cách nào để phân tích ngày trong bash, với các trường riêng biệt (năm, tháng, ngày, giờ, phút, giây) thành các biến khác nhau?Ngày phân tích cú pháp trong Bash
Định dạng ngày là: YYYY-MM-DD hh:mm:ss
Liệu nó phải bash? Bạn có thể sử dụng coreutils /bin/date
nhị phân GNU đối với nhiều biến đổi:
$ date --date="2009-01-02 03:04:05" "+%d %B of %Y at %H:%M and %S seconds"
02 January of 2009 at 03:04 and 05 seconds
này phân tích các ngày nhất định và hiển thị nó trong định dạng lựa chọn. Bạn có thể điều chỉnh theo ý muốn theo nhu cầu của bạn.
$ t='2009-12-03 12:38:15'
$ a=(`echo $t | sed -e 's/[:-]/ /g'`)
$ echo ${a[*]}
2009 12 03 12 38 15
$ echo ${a[3]}
12
không cần phải gọi lệnh bên ngoài – ghostdog74
bạn đã thử sử dụng cắt chưa? một cái gì đó như thế này: DAYOFWEEK = date|cut -d" " -f1
Điều đó chỉ tách ngày và giờ chứ không phải từng phần riêng lẻ. –
tinh khiết Bash:
date="2009-12-03 15:35:11"
saveIFS="$IFS"
IFS="- :"
date=($date)
IFS="$saveIFS"
for field in "${date[@]}"
do
echo $field
done
2009
12
03
15
35
11
Không cần sử dụng mảng ở đây. Chỉ cần 'set junk $ date; shift' thay vì 'date = ($ date)' và 'cho field' thay vì vòng lặp mảng. Đó sẽ là một phiên bản 'thuần túy sh', thậm chí còn tốt hơn! – Idelic
khác bash tinh khiết
$ d="2009-12-03 15:35:11"
$ d=${d//[- :]/|}
$ IFS="|"
$ set -- $d
$ echo $1
2009
$ echo $2
12
$ echo [email protected]
2009 12 03 15 35 11
Phương pháp mảng có lẽ là tốt hơn, nhưng đây là những gì bạn đã yêu cầu cụ thể đối với:
IFS=" :-"
read year month day hour minute second < <(echo "YYYY-MM-DD hh:mm:ss")
Tôi thích điều này nhất. Một phím tắt, cũng không thay đổi vĩnh viễn IFS: 'IFS =": - "đã đọc YMYY-MM-DD hh: mm: ss" – ephemient
Điều này là đơn giản, chỉ cần chuyển đổi dấu gạch ngang và dấu hai chấm của bạn đến một không gian (không cần phải thay đổi IFS) và sử dụng 'đọc' trên cùng một dòng:
read Y M D h m s <<< ${date//[-:]/ }
Ví dụ:
$ date=$(date +'%Y-%m-%d %H:%M:%S')
$ read Y M D h m s <<< ${date//[-: ]/ }
$ echo "Y=$Y, m=$m"
Y=2009, m=57
thay vì sử dụng vỏ kịch bản, kết hợp chặt chẽ trong kịch bản của bạn tự như dưới đây wheever bạn cần:
a=date +%Y
b=date +%S
c=date +%H
một sẽ là năm b sẽ là giây c sẽ giờ. và vân vân.
Một giải pháp cho vấn đề của OP:
IFS=' -:' read y m d h m s<<<'2014-03-26 16:36:41'
Chuyển đổi một ngày sang định dạng khác với BSD date
và GNU date
:
$ LC_ALL=C date -jf '%a %b %e %H:%M:%S %Z %Y' 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
$ gdate -d 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
GNU date
nhận Wed
và Mar
ngay cả trong phi Miền địa phương tiếng Anh nhưng BSD date
thì không.
Chuyển đổi giây kể từ kỷ nguyên đến một ngày và thời gian với ngày tháng và BSD ngày GNU:
$ gdate -d @1234567890 '+%F %T'
2009-02-14 01:31:30
$ date -r 1234567890 '+%F %T'
2009-02-14 01:31:30
Chuyển đổi giây để giờ, phút và giây với một vỏ POSIX, POSIX awk
, GNU date
, và BSD date
:
$ s=12345;printf '%02d:%02d:%02d\n' $((s/3600)) $((s%3600/60)) $((s%60))
05:25:45
$ echo 12345|awk '{printf "%02d:%02d:%02d\n",$0/3600,$0%3600/60,$0%60}'
05:25:45
$ gdate -d @12345 +%T
05:25:45
$ date -r 12345 +%T
05:25:45
Chuyển đổi giây đến vài ngày, giờ, phút và giây:
$ t=12345678
$ printf '%d:%02d:%02d:%02d\n' $((t/86400)) $((t/3600%24)) $((t/60%60)) $((t%60))
142:21:21:18
Tôi có định dạng thời gian nhập khác nhau, do đó, đây là giải pháp linh hoạt hơn. Lệnh chuyển đổi ngày trong BSD/macOS là
date -jf in_format [+out_format] in_date
nơi định dạng sử dụng strftime (xem man strftime
).
Đối với định dạng đầu vào cho YYYY-MM-DD hh:mm:ss
:
$ date -jf '%Y-%m-%d %H:%M:%S' '2017-05-10 13:40:01'
Wed May 10 13:40:01 PDT 2017
Để đọc chúng vào các biến riêng biệt, tôi lấy ý tưởng NVRAM, nhưng cho phép bạn sử dụng bất kỳ định dạng strftime:
$ date_in='2017-05-10 13:40:01'
$ format='%Y-%m-%d %H:%M:%S'
$ read y m d H M S <<< "$(date -jf "$format" '+%Y %m %d %H %M %S' "$date_in")"
$ for var in y m d H M S; do echo "$var=${!var}"; done
y=2017
m=05
d=10
H=13
M=40
S=01
Trong tôi trường hợp, tôi muốn chuyển đổi giữa các múi giờ (xem thư mục /usr/share/zoneinfo
của bạn cho tên vùng):
$ format=%Y-%m-%dT%H:%M:%S%z
$ TZ=UTC date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-10T00:40:01+0000
$ TZ=America/Los_Angeles date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-09T17:40:01-0700
Đây có phải là phần mở rộng Linux không? Cả FreeBSD hoặc Mac OSX dường như không hỗ trợ nó. –
Đây là ngày cũ GNU cũ: $ date --version ngày (GNU coreutils) 7.4 Bản quyền (C) 2009 Free Software Foundation, Inc. Giấy phép GPLv3 +: GNU GPL phiên bản 3 hoặc mới hơn. Đây là phần mềm miễn phí: bạn có thể tự do thay đổi và phân phối lại nó. KHÔNG CÓ BẢO HÀNH, trong phạm vi pháp luật cho phép. Được viết bởi David MacKenzie. –
Tại sao 'date --date =" \ 'date \' "' không hoạt động? – Luc