将多列中的时间戳更改为正确的日期(例如 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()
枚举了可以包含时间戳的字段。
我有以下文件:
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()
枚举了可以包含时间戳的字段。