将多列中的时间戳更改为正确的日期(例如YYYYMMDD)

时间:2015-02-18 15:11:36

标签: bash date awk sed timestamp

我有以下文件:

91001440737;1421687191;1421687966;10;true;true;1421816564;;;;;;;;;
91001477235;1422551333;;3;true;true;;;;;;1422789053;;;1422789053;
91001512152;;1423070412;2;true;true;;;;;;1423134381;;;;
91001520460;1421600655;;13;true;true;1421665705;;;;1422443201;;;;;
91001627323;1422724554;;10;true;true;1422939818;;;;;;;;;
91001680088;1421535875;;2;true;true;;;1422680695;;;1421579247;;;;

某些列(如第2列和第3列以及其他列)具有时间戳。我想把它们改成正确的日期。

我使用以下命令行来执行此操作:

cat fic_v1_entier.txt | while read line ; do echo $line\;$(date +%Y/%m/%d) ; done

但是命令行不正确,因为它给了我这个结果:

91001680088;1421535875;;2;true;true;;;1422680695;;;1421579247;;;;;2015/02/18

正如您所看到的,当我希望更改第2列,第3列以及其他特定列时,只更改了最后一列。

欢迎任何提示。

3 个答案:

答案 0 :(得分:4)

可以使用awk

轻松完成
awk -F\; 'BEGIN{OFS=";"}
         { $2 = strftime("%Y/%m/%d",$2)
           $3 = strftime("%Y/%m/%d",$3)}1'

<强>测试

此处仅更改了第二个和第三个($2$3)。

$ awk -F\; 'BEGIN {OFS=";"} { $2 = strftime("%Y/%m/%d",$2); $3 = strftime("%Y/%m/%d",$3)}1'

91001440737;2015/01/19;2015/01/19;10;true;true;1421816564;;;;;;;;;
91001477235;2015/01/29;1970/01/01;3;true;true;;;;;;1422789053;;;1422789053;
91001512152;1970/01/01;2015/02/04;2;true;true;;;;;;1423134381;;;;
91001520460;2015/01/18;1970/01/01;13;true;true;1421665705;;;;1422443201;;;;;
91001627323;2015/01/31;1970/01/01;10;true;true;1422939818;;;;;;;;;
91001680088;2015/01/18;1970/01/01;2;true;true;;;1422680695;;;1421579247;;;;

答案 1 :(得分:3)

例如,您可以说:

while IFS=";" read -r f1 f2 f3
do
    printf "%s;%s;%s\n" "$f1" $([ -n "$f2" ] && date -d@"$f2" "+%F%T" || echo "") "$f3"
done < file

即,阅读每个字段并将date应用于所需字段。要对其他变量执行相同操作,您需要说read -r f1 f2 f3 ... fN并应用相同的逻辑。

注意我使用%F%T格式,而您可以说%Y%m%d或您喜欢的任何内容。要进行转换,我使用表达式date -d@timestamp "+format"

另请注意,您说cat file | while ...,而while ... < file绰绰有余甚至更好:I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?

测试

$ while IFS=";" read -r f1 f2 f3; do printf "%s;%s;%s\n" "$f1" $([ -n "$f2" ] && date -d@"$f2" "+%F%T" || echo "") "$f3"; done < file
91001440737;2015-01-1918:06:31;1421687966;10;true;true;1421816564;;;;;;;;;
91001477235;2015-01-2918:08:53;;3;true;true;;;;;;1422789053;;;1422789053;
91001512152;1423070412;2;true;true;;;;;;1423134381;;;;;
91001520460;2015-01-1818:04:15;;13;true;true;1421665705;;;;1422443201;;;;;
91001627323;2015-01-3118:15:54;;10;true;true;1422939818;;;;;;;;;
91001680088;2015-01-1800:04:35;;2;true;true;;;1422680695;;;1421579247;;;;

答案 2 :(得分:1)

将GNU awk用于字符串函数:

$ cat tst.awk
BEGIN {
    FS=OFS=";"
    split("2 3 7 9 11 12 15",tsFlds,/ /)
}
{
    for (i=1; i in tsFlds; i++) {
        if ($(tsFlds[i]) != "") {
            $(tsFlds[i]) = strftime("%Y/%m/%d",$(tsFlds[i]))
        }
    }
    print
}
$ 
$ gawk -f tst.awk file
91001440737;2015/01/19;2015/01/19;10;true;true;2015/01/20;;;;;;;;;
91001477235;2015/01/29;;3;true;true;;;;;;2015/02/01;;;2015/02/01;
91001512152;;2015/02/04;2;true;true;;;;;;2015/02/05;;;;
91001520460;2015/01/18;;13;true;true;2015/01/19;;;;2015/01/28;;;;;
91001627323;2015/01/31;;10;true;true;2015/02/02;;;;;;;;;
91001680088;2015/01/17;;2;true;true;;;2015/01/30;;;2015/01/18;;;;

split()枚举可以包含时间戳的字段。