【问题标题】:Sed with inner command and with regex group reference带有内部命令和正则表达式组参考的 Sed
【发布时间】:2018-08-28 05:09:11
【问题描述】:

我一直在努力解决以下问题:

我有一个包含以下内容的文件

1521471079313,219,HTTP Request 14,200,OK,PROD 50 rpm 1-10,text,true,,17665,204,1,1,177,0,35
1521471080337,263,HTTP Request 11,200,OK,PROD 50 rpm 1-10,text,true,,30268,202,1,1,169,0,0
1521471081404,245,HTTP Request 12,200,OK,PROD 50 rpm 1-10,text,true,,5134,201,1,1,210,0,37
1521471082453,125,HTTP Request 13,200,OK,PROD 50 rpm 1-10,text,true,,8910,201,1,1,106,0,0
1521471083381,217,HTTP Request 14,200,OK,PROD 50 rpm 1-10,text,true,,17665,204,1,1,188,0,0
1521471084402,303,HTTP Request 11,200,OK,PROD 50 rpm 1-10,text,true,,30268,202,1,1,226,0,41

列表中的第一项是 epoc 时间戳,我想将其转换为人类可读的。

我尝试了以下命令

cat file.csv|sed -E  "s/^([0-9]*)(,.*)/$(date -r \1 '+%m-%d-%Y:%H:%M:%S')\2/p"

它似乎有效,但后来我看到它会将其转换为:

01-01-1970:01:00:01,245,HTTP Request 13,200,OK,PROD 50 rpm 1-10,text,true,,8910,201,1,1,219,0,43
01-01-1970:01:00:01,276,HTTP Request 14,200,OK,PROD 50 rpm 1-10,text,true,,17665,204,1,1,217,0,0
01-01-1970:01:00:01,276,HTTP Request 14,200,OK,PROD 50 rpm 1-10,text,true,,17665,204,1,1,217,0,0
01-01-1970:01:00:01,242,HTTP Request 11,200,OK,PROD 50 rpm 1-10,text,true,,30268,202,1,1,216,0,34
01-01-1970:01:00:01,242,HTTP Request 11,200,OK,PROD 50 rpm 1-10,text,true,,30268,202,1,1,216,0,34
01-01-1970:01:00:01,147,HTTP Request 12,200,OK,PROD 50 rpm 1-10,text,true,,5134,201,1,1,119,0,0
01-01-1970:01:00:01,147,HTTP Request 12,200,OK,PROD 50 rpm 1-10,text,true,,5134,201,1,1,119,0,0

所有时间戳看起来都像“时间的开始 :-)”,而不是我想要的。

我知道我在 sed 中有一个命令替换,还有两个基于 sed 命令中的前正则表达式的组引用,但为什么它不起作用让我很困惑。

【问题讨论】:

    标签: bash macos sed


    【解决方案1】:

    您可以使用 GNU awk 轻松解析 csv 文件。您的 $1 值是以毫秒为单位的 EPOCH 值。您可以使用strftime() 调用打印人类可读的格式,将值除以 1000(即转换为秒)

    awk 'BEGIN{FS=OFS=","}{$1=strftime("%c",($1/1000))}1' file
    

    对于就地编辑,使用gawk 或将输出移动到临时文件并将其恢复为原始文件

    tmpfile=$(mktemp /tmp/abc.XXXXXX)
    awk 'BEGIN{FS=OFS=","}{$1=strftime("%c",($1/1000))}1' file > "$tmpfile"
    mv "$tmpfile" file
    

    【讨论】:

    • 这是要走的路。
    • 可能是正确的,但问题确实是针对 sed 的,因为我还对如何让组引用在 sed 上的内部命令中工作感兴趣。而且strftime似乎不适用于macos awk: calling undefined function strftime
    • 谢谢!在我的 Mac 上安装 gawk 后它运行良好!我必须感谢@user-unknown,因为他的答案更接近我的问题,而且这个答案也很有效,即使它是“肮脏的”
    • @Ivonet:干杯!没问题
    【解决方案2】:

    这对我有用:

    sed -r "s/^([0-9]+)(,.*)/echo \$(date -d @\1)\2/" sampl3.log > log.sh && bash log.sh  
    

    但您必须确保日志中不包含任何恶意命令,并调整您的日期格式。

    Mi 2. Jul 01:21:53 CEST 50183,219,HTTP Request 14,200,OK,PROD 50 rpm 1-10,text,true,,17665,204,1,1,177,0,35
    Mi 2. Jul 01:38:57 CEST 50183,263,HTTP Request 11,200,OK,PROD 50 rpm 1-10,text,true,,30268,202,1,1,169,0,0
    Mi 2. Jul 01:56:44 CEST 50183,245,HTTP Request 12,200,OK,PROD 50 rpm 1-10,text,true,,5134,201,1,1,210,0,37
    Mi 2. Jul 02:14:13 CEST 50183,125,HTTP Request 13,200,OK,PROD 50 rpm 1-10,text,true,,8910,201,1,1,106,0,0
    Mi 2. Jul 02:29:41 CEST 50183,217,HTTP Request 14,200,OK,PROD 50 rpm 1-10,text,true,,17665,204,1,1,188,0,0
    Mi 2. Jul 02:46:42 CEST 50183,303,HTTP Request 11,200,OK,PROD 50 rpm 1-10,text,true,,30268,202,1,1,226,0,41
    

    【讨论】:

    • 这是在杀死时间戳的最后一个树数字后真正为我工作的那个:sed -E "s/^([0-9]{10})[0-9]{3}(,.*)/echo \$(date -r \1 '+%m-%d-%Y:%H:%M:%S')\2/" rpm_50_prod_res.csv > log.sh && bash log.sh 这是因为您提供的某些参数在 Mac 上不起作用......忘了告诉那
    • 嗯,我的印象是,具体的日期格式和 sed 语法都不是问题,而是 sed 函数中 \1 的评估时间,这不起作用。
    猜你喜欢
    • 2020-05-21
    • 1970-01-01
    • 2013-08-07
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多