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

change timestamp in multiple columns to proper date (e.g YYYYMMDD)

我有以下文件:

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 列以及其他特定列时,只更改了最后一列。

欢迎任何提示。

例如你可以说:

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;;;;

也许这可以使用 awk 轻松完成

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

测试

这里只修改了第二个和第三个(</code>和<code>

$ awk -F\; 'BEGIN {OFS=";"} {  = strftime("%Y/%m/%d",);  = strftime("%Y/%m/%d",)}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;;;;

将 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()枚举了可以包含时间戳的字段。