我有一个 CSV,其中包含不同程序的命令的输出,time
包括执行的 ID。
因此我的文件包含以下形式的记录:
ID,execution_time
示例记录:
345,0m0.047s
我只需要执行次数和秒数。
因此,上述记录需要
345,0047
(没有“0m”,“。”和“s”)。
有可能实现吗?
答案1
如果有分钟怎么办?下面是将其转换为秒的方法:
awk -F'[m,]' '{print $1 "," $2*60 + $3}' file.csv
还有一些演示:
$ ... <(echo -e "345,0m0.047s\n345,1m0.047s\n345,1m2.047s")
345,0.047
345,60.047
345,62.047
我不确定你为什么要删除小数点,但你可以传递输出,sed 's/\.//g'
如果你真的需要:
$ ... <(echo -e "345,0m0.047s\n345,1m0.047s\n345,1m2.047s") | sed 's/\.//g'
345,0047
345,60047
345,62047
呃。
假设这是一个time
输出,如果值包含小时甚至天怎么办?我尝试了一下,想出了这个小妙招:
awk -F'[dhms,]' 'BEGIN{split("1 60 3600 86400", T, " ")}{t=0; for (i=NF-1; i>1; i--) t+=T[NF-i]*$i; printf("%s,%.3f\n", $1, t)}'
这将处理以下格式:*s
*m*s
*h*m*s
和*d*h*m*s
并将它们全部转换为秒(保留三位小数)。强制性演示时间:
$ ... <(echo -e "345,1.2s\n345,12m5s\n345,1h2m5s\n345,1d2h1m2.047s")
345,1.200
345,725.000
345,3725.000
345,93662.047
答案2
以下是我的解决方案:
sed -i 's/[0-9]*m\|s\|\.//g' file.csv
您可能想要跳过第一行,如果它包含标题,如下所示:
sed -i '2,$s/[0-9]*m\|s\|\.//g' file.csv
请注意,该-i
选项会导致sed
“就地”工作,从而改变原始文件。如果您想创建一个新文件,请使用以下命令:
sed 's/[0-9]*m\|s\|\.//g' file.csv > new_file.csv
答案3
它应该是:
sed 's/m0\.\(.*\)s$/\1/g'
答案4
@kraxor 的答案是sed
删除行中的“其他所有内容”,然后只显示该行。
但实际上“其他一切”? 至少从一行样本中我们能得出一个想法。但是当我们得到 CSV 标题行时该怎么办?要删除什么?
一般来说,我们不知道。
因此,实际上显示我们想要显示的数据!
echo '345,0m0.047s' | sed -n -r 's/^(.*),.*[^0-9]([0-9]*)\.(.*)s$/\1,\2\3/p'
345,0047
到目前为止有效!
它有什么作用?
我们通常不打印该行(-n
)
(并激活更好的“扩展正则表达式”(-r
))现在查找 ID、秒和秒的小数部分,
如果找到它们,则以正确的格式(添加“,”)将它们放入行中,
然后打印新创建的行。
现在一些其他输入,很正常,有两行数据:
ID,execution_time
123, Oops a comment0m0.0333s
345,0m0.047s
嗯?!看起来真实世界数据, 实际上!
echo "ID,execution_time\n123, Oops a comment0m0.0333s\n345,0m0.047s" | sed -r -n 's/^(.*),.*[^0-9]([0-9]*)\.(.*)s$/\1,\2\3/p'
123,00333
345,0047
看上去很漂亮,正好!
为了证明这样做有一定优点,我将与之前的答案进行比较:
echo "ID,execution_time\n123, Oops a comment0m0.0333s\n345,0m0.047s" | sed 's/[0-9]*m\|s\|\.//g'
ID,execution_tie
123, Oop a coent00333
345,0047
好的,实际的、干净的数据线顺利通过了;
但其他部分,情况就不怎么样了(注意,标题不只是通过了,而且被切断了)。
(请注意,有一个解决方案可以明确跳过标题行(或者可能是第一个数据行,我们知道吗?))