我有一个包含以下输入示例数据的文件:
1137921146.499 180900 61.153.158.197 1409
1137921158.698 181622 61.153.158.197 1409
1137921758.163 180026 221.226.124.114 1374
1137921802.016 179485 121.13.128.132 1409
第一列是 unix 纪元时间戳,我需要将其转换为人类可读的格式,并且我希望数据按如下方式分隔
Sun Jan 22 01:12:26 PST 2006|180900|61.153.158.197|1409
Sun Jan 22 01:12:38 PST 2006|181622|61.153.158.19|1409
我尝试使用 sed 's/ {1,}/|/g' 添加分隔符并使用 date -d @1137921146.499 转换日期。但我无法用一个命令将这两个组合在一起..
答案1
您可以像这样使用 awk 程序:
awk '{ print strftime("%c",$1)"|" $2"|"$3"|"$4 }' file
核心是使用strftime函数将epoch转换为日期格式
这是输出:
#awk '{ print strftime("%c",$1)"|" $2"|"$3"|"$4 }' file
Sun Jan 22 10:12:26 2006|180900|61.153.158.197|1409
Sun Jan 22 10:12:38 2006|181622|61.153.158.197|1409
Sun Jan 22 10:22:38 2006|180026|221.226.124.114|1374
Sun Jan 22 10:23:22 2006|179485|121.13.128.132|1409
PS 或者您可以使用隐式输出分隔符:
awk 'BEGIN { OFS="|"} {$1= strftime("%c",$1) }1' file
答案2
使用您已经知道的知识:
- GNU
date
可以通过给定 来将时间戳转换为格式化日期@timestamp
。 - 将空格替换为
|
将为您提供所需的输出。
为此,我们添加
- GNU
date
可以对文件进行操作,批量转换日期。
要使用 GNU 批量转换日期,date
我们必须提取时间戳并添加前缀@
:
$ sed 's/^\([^ ]*\).*$/@\1/' data.in
@1137921146.499
@1137921158.698
@1137921758.163
@1137921802.016
该sed
表达式将每一行替换为前缀为 的第一个空格分隔字段@
。
使用bash
(和ksh93
,或任何理解进程替换的 shell):
$ date -f <( sed 's/^\([^ ]*\).*$/@\1/' data.in )
Sun Jan 22 10:12:26 CET 2006
Sun Jan 22 10:12:38 CET 2006
Sun Jan 22 10:22:38 CET 2006
Sun Jan 22 10:23:22 CET 2006
然后我们需要获取输入数据的其他字段并替换分隔符:
$ cut -d ' ' -f 2- data.in | tr ' ' '|'
180900|61.153.158.197|1409
181622|61.153.158.197|1409
180026|221.226.124.114|1374
179485|121.13.128.132|1409
然后我们将这两件事与|
分隔符粘贴在一起:
$ paste -d '|' <( date -f <( sed 's/^\([^ ]*\).*$/@\1/' data.in ) ) <( cut -d ' ' -f 2- data.in | tr ' ' '|' )
Sun Jan 22 10:12:26 CET 2006|180900|61.153.158.197|1409
Sun Jan 22 10:12:38 CET 2006|181622|61.153.158.197|1409
Sun Jan 22 10:22:38 CET 2006|180026|221.226.124.114|1374
Sun Jan 22 10:23:22 CET 2006|179485|121.13.128.132|1409
答案3
或者用你的外壳:
while read timestamp pid ip port; do
echo "$(date -d @$timestamp)|$pid|$ip|$port"
done <yourfile