我正在使用一個帶有curl的API,它以UNIX Epoch time而不是ISO8601提供欄位的日期資訊,這使得我難以理解發生了什么。
輸入示例:
{" message": "域名串列","串列":[{"域名":"例子。
是否有辦法在這個資料流中找到任何看起來像UNIX紀元時間的東西(例如,代表最近的時間--任何引號內的10位數字,過去的1000000000(根據env TZ=GMT-3 date -r1000000000 %Y-%m-%dT%H%M%S%z與BSD date(1)),并將其全部轉換為類似ISO8601的日期,用perl或BSD awk的小shell腳本片段?
期望的輸出(有或沒有時區偏移):
{"message":"Domains list","list":[
{"域名":"example. org","created":"2015-09-24T000000 0300","regtill":"2021-09-24T000000 0300"}]}
uj5u.com熱心網友回復:
你可以使用jq,這是一個操作JSON的偉大工具。
jq '
( .. | select(type == "string") | select(try tonumber | . > 1000000000) ) |=
( tonumber | todateiso8601 )
'
uj5u.com熱心網友回復:
Perl腳本在標準輸入上讀取你的JSON,所以它可以有curl輸出管道:
#!/usr/bin/env perl。
use strict;
使用警告。
use feature qw/say/;
use experimental qw/postderef/;
use Time::Piece;
# 通過你的作業系統包管理器安裝,如果提供或收藏。
# CPAN客戶端。或者使用你更喜歡的其他JSON模塊;perl
# 有相當多的可用模塊。最壞的情況是,如果你不能安裝任何
# 額外的模塊是使用核心JSON::PP。
使用 JSON::MaybeXS。
my $json = JSON::MaybeXS-> new-> utf8;
my $rawdata = do { local $/; < STDIN> };
my $data = $json>decode($rawdata);
for my $domain ($data-> {list}->@*) {
$domain->{created} = localtime($domain->{created})-> datetime;
$domain->{regtill} = localtime($domain->{regtill})->datetime。
}
say $json>encode($data);
例子:
$ ./convtimes < input.json
{"message":"Domains list","list":[{"created":"2015-09-23T14。 00:00","regtill":"2021-09-23T14:00:00"," domain":"example. org"}]}
uj5u.com熱心網友回復:
這個awk腳本并不出色,但它確實產生了預期的輸出(也許有一些缺陷?
#!/usr/bin/env awk -f
BEGIN {
FS=":|,"; OFS=":"; RS="[")
} NR==1 {
$NF="["
} NR>1 {
gsub(/"/,")。
4=strftime("%Y-%m-%dT%H%M%S%z",4)。
$6=strftime("%Y-%m-%dT%H%M%S%z}]}",$6);
gsub(/:/,":")。
sub(/{/,"{")。
sub(/}/,"}"")
} 1
或者作為一個單行本
awk 'BEGIN {FS=":|,"; OFS=":"; RS="["} NR==1 {$nf="["} NR>1 {gsub(/"/,"); 4=strftime("%Y-%m-%dT%H%M%S%z",4);6=strftime("%Y-%m-%dT%H%M%S%z}]}",6); gsub(/:/,":"); sub(/{/, "{"); sub(/}/, "}")}1' /span> input_file
輸出
{"message":"Domains list":"list":[
{"域名":"example. org":"created":"2015-09-23T220000 0100":"regtill":"2021-09-23T220000 0100}"]}
uj5u.com熱心網友回復:
到目前為止,最好的片段是由simbabque在評論中提供的:
$ perl -MTime::Piece -pe 's/(d{10,})/{localtime(1)->datetime}/ge' <<<'{"message": "Domains list", "list":[{"domain": "example.org", "created": "1443042000", "regtill": "1632430800"}}'/code> - 你可以通過這個管你的curl。-
simbabque 1小時前
我對它做了進一步的調整,具體如下:
:"和"使用了正向的lookbehind和lookahead,分別用(?<=:")和(?="),以避免假陽性;env TZ=GMT perl -MTime::Piece -e 'print localtime(1000000000)->datetime, "Z/", localtime(999999999)-> datetime, "Z "'2001-09-09T01:46:40Z/2286-11-20T17:46:39Z
最簡單的片段:
curl ...
| perl -MTime::Piece -pe's#(d{10})#localtime(1)->datetime#ge'
為引號增加lookbehind/lookahead:
curl ...
| perl -MTime::Piece -pe's#(?<=")(d{10})(?=")#localtime(1)->datetime#ge'
指定輸入資料的時區,同時為串列中的每個域插入換行符,以使其更具用戶可讀性:
指定輸入資料的時區。
curl ...
| env TZ=GMT-3 perl -MTime::Piece
-pe 's#:[{#:[
{#g;s#},{#},
{#g;s#(?<=:")(d{10})(?=")#localtime(1)->datetime#ge'
整體轉換的最終解決方案的樣本測驗運行 -- 在任何資料流上都可以作業,忽略任何不是JSON的東西,在無效的JSON上不會出現任何錯誤:
% printf '{"list":[{"d": "abc", "c": "1443042000"},{"d": "xyz", "c": "1000000000"}] }
'
| env TZ=GMT-3 perl -MTime::Piece -pe
's#:[{#:[
{#g;s#},{#},
{#g;s#(?<=:")(d{10})(?=")#localtime(1)->datetime#ge'
{"list":[
{"d":"abc","c":"2015-09-24T00:00"}。
{"d":"xyz","c":"2001-09-09T04:46:40"}】。}
這個方案比其他假定輸入是有效的JSON的方案更靈活,因為它也可以用于單個curl命令被用來做多個請求的情況,這不會是一個有效的JSON,因為JSON只能有一個根元素。 它也更靈活,因為它甚至不假設輸入資料是任何特定的格式--任何在:"和"之間的10位數字都將被自動從UNIX Epoch time轉換為ISO8601,完全按照問題中的規定。
uj5u.com熱心網友回復:
使用date命令。 這個命令:
date -d '@1443042000'
產生這個答案:
Wed 23 Sep 2015 03:00:00 PM MDT
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/311310.html
標籤:
