Meg*_*ron 5 linux sed awk shell-script text-processing
我有一个带有日期时间的管道分隔文件,格式yyyymmddhhmmss
如下。
John|Doe|TEST|20210728120821|john@test.com
John|Davis|TEST|20210828120821|john@test.com
John|Smith|TEST|20210528120821|john@test.com
Run Code Online (Sandbox Code Playgroud)
我正在尝试将第 4 列中的字符串转换为yyyy-mm-dd hh:mm:ss
这样
John|Doe|TEST|2021-07-28 12:08:21|john@test.com
John|Davis|TEST|2021-08-28 12:08:21|john@test.com
John|Smith|TEST|2021-05-28 12:08:21|john@test.com
Run Code Online (Sandbox Code Playgroud)
由于我不熟悉 Linux 中的文本处理,因此我搜索并尝试使用awk
这样的方法
awk -F"|" '{OFS="|"; $4=strftime("%Y-%m-%d %H:%M:%S", $4); print $0}'
Run Code Online (Sandbox Code Playgroud)
但它没有按预期进行转换。
如果你想使用类似strftime
的方法,那么你可以考虑Miller,它也提供了相应的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
Run Code Online (Sandbox Code Playgroud)
那些“时间戳”不是自操作的时代以来的秒数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|john@test.com
John|Davis|TEST|2021-08-28 12:08:21|john@test.com
John|Smith|TEST|2021-05-28 12:08:21|john@test.com
Run Code Online (Sandbox Code Playgroud)
或使用任何 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|john@test.com
John|Davis|TEST|2021-08-28 12:08:21|john@test.com
John|Smith|TEST|2021-05-28 12:08:21|john@test.com
Run Code Online (Sandbox Code Playgroud)
假设:要更改的字段是唯一或第一个包含 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|='
Run Code Online (Sandbox Code Playgroud)
您的尝试失败,因为$4
需要是UNIX Epoch time (time in seconds since 1970),如GNU Awk 手册文档。