我有一个fb.csv
如下的文件;
"Source","Destination","Time"
"192.168.137.174","157.240.10.18","12:26:25.782658000"
"10.0.138.163","157.240.10.18","12:26:25.782766000"
"157.240.10.13","192.168.137.174","12:26:36.488264000"
"157.240.10.13","10.0.138.163","12:26:36.488178000"
"157.240.10.23","192.168.137.174","12:26:41.808511000"
"157.240.10.23","10.0.138.163","12:26:41.808440000"
"10.0.138.163","157.240.10.18","12:26:52.275093000"
"192.168.137.174","157.240.10.18","12:26:52.275025000"
时间(第 3 列)是一个字符串,我想将其转换为整数,因为我想继续执行查找持续时间的操作。此外,我想删除时间列中“。”后面的所有数字。
期望输出:
"Source","Destination","Time"
"192.168.137.174","157.240.10.18","12:26:25"
"10.0.138.163","157.240.10.18","12:26:25"
"157.240.10.13","192.168.137.174","12:26:36"
"157.240.10.13","10.0.138.163","12:26:36"
"157.240.10.23","192.168.137.174","12:26:41"
"157.240.10.23","10.0.138.163","12:26:41"
"10.0.138.163","157.240.10.18","12:26:52"
"192.168.137.174","157.240.10.18","12:26:52"
有什么方法或功能可以用来做到这一点吗?
答案1
我们可以sed
这样使用:
sed -E 's/\:([0-9])([0-9])\..*"/\:\1\2"/g' fb.csv
@GlennJackman 提供了更好的正则表达式:
冒号不是特殊符号,不需要转义。您不需要单独捕获每个数字。它不需要是全局替换,因为第一个会删除行的其余部分
s/(:[0-9][0-9])\.[0-9]+/\1/
::
sed -E 's/(:[0-9][0-9])\.[0-9]+/\1/' fb.csv
@Dessert 提供了最轻量级的无需扩展正则表达式的解决方案:
sed 's/\.[0-9]*"$/"/' fb.csv
将第三列转换为整数,如果我理解正确的话,我们应该添加第二个表达式:
sed -e 's/\.[0-9]*"$/"/' -e 's/\://g' fb.csv
如果输出看起来足够好,我们可以添加选项-i.bak
来替换它们的位置的值并同时创建备份文件:
sed -e 's/\.[0-9]*"$/"/' -e 's/\://g' fb.csv -i.bak
参考:
答案2
使用 sed:
sed -E 's/(.*)"([0-9]*:[0-9]*:[0-9]*)\.[0-9]*"/\1\2/' fb.csv
删除:
以便可以对最后一列进行操作:
sed -Ee 's/(.*)"([0-9]*:[0-9]*:[0-9]*)\.[0-9]*"/\1\2/' -e 's/\://g' fb.csv
答案3
用于awk
删除最后一个字段中点后面的所有内容。
awk -F\" '{gsub(/\..*$/, "", $(NF-1) )}1' OFS=\" infile
如果您需要计算连续几行中两个时间之间的差值(以秒为单位),请按如下方式使用。
awk -F\" 'function abs(x) {return x<0 ? -x : x}
{ gsub(/\..*$/, "", $(NF-1) ) }
NR>1{ split( $(NF-1), ary, /:/); t_sec= 3600*ary[1] + 60*ary[2] + ary[3];
getline; N=$(NF-1); split( $N, ary, /:/); t_sec_N= 3600*ary[1] + 60*ary[2] + ary[3];
print abs(t_sec - t_sec_N);
}' OFS=\" infile
函数借用自@glenn 的回答