在使用SED将时间戳替换为人类可读的日期时,时间戳始终替换为纪元日期加上“ \”之后的值
我在Perl示例中使用了此方法,但更喜欢使用sed。我已经尝试过更改转义序列并引用“'`等”。
sed -re "s/([0-9]{10})/$(date -d @\1)/g" mac.txt
输入(一个字符串):
834|task|3||1561834555|Ods|12015|info|Task HMI starting 837|task|3||1561834702|Nailsd|5041|info|Configured with engine 6000.8403 (/opt/NAI/LinuxShield/engine/lib/liblnxfv.so), dats 9297.0000 (/opt/NAI/LinuxShield/engine/dat), 197 extensions, 0 extra drivers
期望日期转换,但结果是:
834|task|3||Wed Dec 31 19:00:01 EST 1969|Ods|12015|info|Task HMI starting 837|task|3||Wed Dec 31 19:00:01 EST 1969|Nailsd|5041|info|Configured with engine 6000.8403 (/opt/NAI/LinuxShield/engine/lib/liblnxfv.so), dats 9297.0000 (/opt/NAI/LinuxShield/engine/dat), 197 extensions, 0 extra drivers 838|task.
基本上: 这就是所谓的:
$(date -d @\1) instead of $(date -d @\1561834555)
答案 0 :(得分:1)
sed从来没有看到$(date -d @\1)
- shell在sed启动前执行了命令替换。
您可以这样:
sed -Ee 's/([0-9]{10})/$(date -d @\1)/g' -e 's/^/echo "/' -e 's/$/"/' mac.txt | sh
(请注意单引号,以防止shell进行任何扩展)
然而,使用内置日期功能的语言更为明智。 GNU awk:
gawk -F '|' -v OFS='|' '{
for (i=1; i<=NF; i++)
if ($i ~ /^[0-9]{10}$/)
$i = strftime("%c", $i)
print
}' mac.txt
可能会安装Perl:
perl -MPOSIX=strftime -pe 's{\b(\d{10})\b}{ strftime("%c", localtime $1) }ge' mac.txt
# or, this is more precise as it only substitutes *fields* that consist of a timestamp
perl -MPOSIX=strftime -F'\|' -lape '$_ = join "|", map { s/^(\d{10})$/ strftime("%c", localtime $1) /ge; $_ } @F' mac.txt