我有一个以管道分隔的文件,其日期时间格式yyyymmddhhmmss
如下。
John|Doe|TEST|20210728120821|[email protected]
John|Davis|TEST|20210828120821|[email protected]
John|Smith|TEST|20210528120821|[email protected]
我正在尝试将第 4 列中的字符串转换为yyyy-mm-dd hh:mm:ss
这样
John|Doe|TEST|2021-07-28 12:08:21|[email protected]
John|Davis|TEST|2021-08-28 12:08:21|[email protected]
John|Smith|TEST|2021-05-28 12:08:21|[email protected]
由于我是 Linux 中文本处理的新手,我搜索并尝试使用awk
这样的
awk -F"|" '{OFS="|"; $4=strftime("%Y-%m-%d %H:%M:%S", $4); print $0}'
但它没有按预期进行转换。
答案1
这些“时间戳”不是自纪元以来的秒数strftime()
,它们只是日期+时间,年、月等之间没有分隔符。您只需要简单的文本操作,而不是使用时间函数。
使用 GNU awk(您已经在使用)来执行 gensub():
$ awk 'BEGIN{FS=OFS="|"} {$4=gensub(/(.{4})(..)(..)(..)(..)(..)/,"\\1-\\2-\\3 \\4:\\5:\\6",1,$4)} 1' file
John|Doe|TEST|2021-07-28 12:08:21|[email protected]
John|Davis|TEST|2021-08-28 12:08:21|[email protected]
John|Smith|TEST|2021-05-28 12:08:21|[email protected]
或使用任何 awk:
$ awk 'BEGIN{FS=OFS="|"} {$4=sprintf("%s-%s-%s %s:%s:%s", substr($4,1,4), substr($4,5,2), substr($4,7,2), substr($4,9,2), substr($4,11,2), substr($4,13,2))} 1' file
John|Doe|TEST|2021-07-28 12:08:21|[email protected]
John|Davis|TEST|2021-08-28 12:08:21|[email protected]
John|Smith|TEST|2021-05-28 12:08:21|[email protected]
答案2
如果你想使用strftime
类似的方法,那么你可以考虑磨坊主,其中还提供了相应的strptime
ex。
$ mlr --nidx --fs '|' put -S '
$4 = strftime(strptime($4,"%Y%m%d%H%M%S"),"%Y-%m-%d %H:%M:%S")
' file
John|Doe|TEST|2021-07-28 12:08:21
John|Davis|TEST|2021-08-28 12:08:21
John|Smith|TEST|2021-05-28 12:08:21
答案3
假设:要更改的字段是唯一或第一个恰好包含 14 位数字的字段。
sed -E 's=\|([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})\|=|\1-\2-\3 \4:\5:\6|='
您的尝试失败了,因为$4
需要UNIX 纪元时间(自 1970 年以来的时间,以秒为单位),作为GNU Awk 手册文件。
答案4
我已经写了一些ex
答案,但我找不到有关ex
用于脚本编写的答案。不管怎样,这是一个相当便携的替代方案,不需要安装像 miller 这样的工具:
把这个放进去script.vim
global/|/normal! 03f|lct|^R=strftime('%Y-%m-%d %H:%M:%S', strptime('%Y%m%d%H%M%S', @"))^M
wq
然后跑ex -S script.vim input-file
。 (更改已到位;如果您不喜欢,请调整 to ,或者使用和wq
来获得类似“打印到标准输出”之类的内容。)saveas file
quit!
%print
quit!
使^R
和^M
为文字 control-R 和 control-M 或回车符(在 vim 中,例如Ctrl- V Ctrl- R)。