Numpy 如何有选择地使用sed或awk(关于行长度)(逐个文件)

Numpy 如何有选择地使用sed或awk(关于行长度)(逐个文件),numpy,awk,sed,Numpy,Awk,Sed,我有大约100个以下格式的格式化文件 [[ 1.102 -0.26499999 0. ] [ 2.25999999 -0.88700002 0. ] [-0.152 2.78900003 0. ] [-2.23300004 -1.19700003 0. ] [-2.30699992 1.43700004 0. ]] 其中一些文件位于表单中 [[ -1.22399998e+00 -4

我有大约100个以下格式的格式化文件

[[ 1.102      -0.26499999  0.        ]
 [ 2.25999999 -0.88700002  0.        ]
 [-0.152       2.78900003  0.        ]
 [-2.23300004 -1.19700003  0.        ]
 [-2.30699992  1.43700004  0.        ]]
其中一些文件位于表单中

[[ -1.22399998e+00  -4.05999988e-01  -0.00000000e+00]
 [ -2.00000009e-03   1.70599997e+00   0.00000000e+00]
 [  1.29299998e+00  -3.49999994e-01  -0.00000000e+00]
 [  1.20299995e+00   1.10699999e+00   0.00000000e+00]
 [  2.12299991e+00   1.67100000e+00   0.00000000e+00]]
然而,当我得到这个输出时,这对我来说是不可预测的

我想把这些数字的大写形式四舍五入到三位小数。我尝试过类似于
sed's/^\(.\{8\}\).\{4\}/\1/'file
,但这并不是关于行的长度的具体问题(显然,它也不会对数字进行四舍五入)。
我相信NumPy可以做到这一点,但我认为
sed
awk
会更有效地完成这项工作

其他信息:如果感兴趣,则输出表示坐标并来自pymol,pymol为此使用
NumPy

编辑: 一行中两个小数点之间的字符数是否与示例不同并不重要;以相同的方式格式化所有文件是很有意义的,这意味着

  • 小数点位于相同的三列(字符位置)
  • 每个文件都有相同的数字符号(如十进制、科学)
  • 括号要么位于每个输出/文件的相同位置,要么不在任何输出/文件中
  • 小数的数量在文件中和文件之间都不存在差异
简言之:文件之间的唯一区别是代表数字的数字字符,而不是它们的写入方式、精确程度或位置

上述示例的期望输出:

[[ 1.102      -0.264       0.000    ]
 [ 2.256      -0.887       0.000    ]
 [-0.152       2.789       0.000    ]
 [-2.233      -1.197       0.000    ]
 [-2.307       1.437       0.000    ]]

[[-1.224      -4.056      -0.000    ]
 [-2.000       1.706       0.000    ]
 [ 1.293      -3.500      -0.000    ]
 [ 1.203       1.107       0.000    ]
 [ 2.123       1.671       0.000    ]]
救命啊

perl -lpe 's/([-0-9.e+]+) */sprintf "%.3f ", $1/ge' -- file
  • -l
    从输入中删除换行符并将其添加到输出中
  • -p
    逐行处理输入,并在处理后打印每一行
  • s//
    是替换,类似于sed中的同一命令
  • /e
    将替换解释为代码并运行它,在本例中,这意味着每个数字的格式都是使用
Perl来营救

perl -lpe 's/([-0-9.e+]+) */sprintf "%.3f ", $1/ge' -- file
  • -l
    从输入中删除换行符并将其添加到输出中
  • -p
    逐行处理输入,并在处理后打印每一行
  • s//
    是替换,类似于sed中的同一命令
  • /e
    将替换解释为代码并运行它,在本例中,这意味着每个数字的格式都是使用

printf
中调整输出间距,以适应任何适用于您的标准,如果这不符合以下条件:

$ cat tst.awk
{
    gsub(/[][]+/," & ")
    for (i=2; i<NF; i++) {
        $i = sprintf("%.3f",$i)
    }
    printf "%2s%6s%12s%12s    %-2s\n", $1, $2, $3, $4, $5
}
以上操作是针对此输入文件运行的:

$ cat file
[[ 1.102      -0.26499999  0.        ]
 [ 2.25999999 -0.88700002  0.        ]
 [-0.152       2.78900003  0.        ]
 [-2.23300004 -1.19700003  0.        ]
 [-2.30699992  1.43700004  0.        ]]

[[ -1.22399998e+00  -4.05999988e-01  -0.00000000e+00]
 [ -2.00000009e-03   1.70599997e+00   0.00000000e+00]
 [  1.29299998e+00  -3.49999994e-01  -0.00000000e+00]
 [  1.20299995e+00   1.10699999e+00   0.00000000e+00]
 [  2.12299991e+00   1.67100000e+00   0.00000000e+00]]

printf
中调整输出间距,以符合任何适用于您的标准,如果这不符合要求:

$ cat tst.awk
{
    gsub(/[][]+/," & ")
    for (i=2; i<NF; i++) {
        $i = sprintf("%.3f",$i)
    }
    printf "%2s%6s%12s%12s    %-2s\n", $1, $2, $3, $4, $5
}
以上操作是针对此输入文件运行的:

$ cat file
[[ 1.102      -0.26499999  0.        ]
 [ 2.25999999 -0.88700002  0.        ]
 [-0.152       2.78900003  0.        ]
 [-2.23300004 -1.19700003  0.        ]
 [-2.30699992  1.43700004  0.        ]]

[[ -1.22399998e+00  -4.05999988e-01  -0.00000000e+00]
 [ -2.00000009e-03   1.70599997e+00   0.00000000e+00]
 [  1.29299998e+00  -3.49999994e-01  -0.00000000e+00]
 [  1.20299995e+00   1.10699999e+00   0.00000000e+00]
 [  2.12299991e+00   1.67100000e+00   0.00000000e+00]]

+1在一行中使用这个几乎可以工作的解决方案(我希望使用两个,因为每行有两个位置需要更换)。不幸的是,当数字不包含负号时,它没有给我额外的空间(条)。如果你能修改这个优雅的解决方案,同时使用部分有符号的数字,那就太好了。你能用给定输入文件的预期输出更新这个问题吗?+1在一行中使用这个几乎可以工作的解决方案(我希望两个,因为每行要替换两个位置)。不幸的是,当数字不包含负号时,它没有给我额外的空间(条)。如果你能修改这个优雅的解决方案,同时使用部分签名的数字,那就太好了。你能用给定输入文件的预期输出更新这个问题吗?