使用 sed/grep 从一行中获取数字模式



我有如下行流

iter: 0 ival: 0, fcost =               0
iter: 0 ival: 1, fcost =               1
iter: 0 ival: 2, fcost =    0.7115281224
iter: 1 ival: 3, fcost =    0.3990854323
iter: 2 ival: 4, fcost =    0.1486154944
iter: 3 ival: 5, fcost =    0.1353816539
iter: 4 ival: 6, fcost =    0.1013548374
iter: 5 ival: 7, fcost =    0.1856721342

我想从这行流中获取逗号或空格分隔的数值。 像这样的东西

0 0 0
0 1 1
0 2 0.7115281224
1 3 0.3990854323
2 4 0.1486154944
3 5 0.1353816539
4 6 0.1013548374
5 7 0.1856721342
5 8 0.08961682022
6 9 0.08508076519

有没有办法使用 grep 或 sed 来做到这一点?

如果您确定行将始终遵循此模式,则可以使用 awk 在给定正确分隔符(在本例中为空格或逗号(的情况下选择适当的列:

awk -F '[, ]+' '{print $2"t"$4"t"$7}' file.txt

-F 选项接受正则表达式,因此将来如果需要,可以选择更好的分隔符。

下面是输出:

$ cat file.txt 
iter: 0 ival: 0, fcost =               0
iter: 0 ival: 1, fcost =               1
iter: 0 ival: 2, fcost =    0.7115281224
iter: 1 ival: 3, fcost =    0.3990854323
iter: 2 ival: 4, fcost =    0.1486154944
iter: 3 ival: 5, fcost =    0.1353816539
iter: 4 ival: 6, fcost =    0.1013548374
iter: 5 ival: 7, fcost =    0.1856721342
$ awk -F '[, ]+' '{print $2"t"$4"t"$7}' file.txt 
0   0   0
0   1   1
0   2   0.7115281224
1   3   0.3990854323
2   4   0.1486154944
3   5   0.1353816539
4   6   0.1013548374
5   7   0.1856721342

编辑: 如注释中所述,在打印结果时,您可能不希望数字之间的分隔符是制表符,因此您可以在上面的示例中选择其他字符而不是"\t"。您还可以使用类似以下内容:

awk -F '[, ]+' '{print $2,$4,$7}' file.txt

它将使用单个空格作为分隔符:

它们是输出的,由单个空格分隔,后跟换行符。

其他选择可能是使用 printf,用于更复杂的组合。

实际上,我找到了我们如何做到这一点的方法。感谢这个答案。基本上我们可以做到这一点

sed 's/[^[0-9.-]]*/ /g;s/ +/ /g;s/^ +| +$//g' filename

其中
s/[^[0-9.-]]*/ /g:用空格
替换所有非数值s/ +/ /g:用单个空格
替换所有空格s/^ +| +$//g:替换所有前后空格

您可以使用 tr 删除不是数字、点或换行符的补充字符集。tr的第二个管道将多个空间压缩到一个可以清理输出。

echo "iter: 5 ival: 7, fcost =    0.1856721342"|tr -cd " .0123456789n"|tr -s " "
5 7 0.1856721342

最新更新