ABC,1234.5333,5733.9374,5673.352,352,2.346374,-0.6686874
XYZ,5463.674,93773.683,5734.874,432,-5.683423,-10.38393
AES,7436874.5743,937.6843,8464.5634,564,6.35739,10.6834
PQR,784945.464,57484.8647,57484.453,5764,-10.67484,5.74764
从上面的 csv 文件中,我需要编写 shell 脚本,该脚本将选择最后两个字段 [ ABS(第 6 个字段)或 ABS(第 7 个字段)] 中任何一个的绝对值 > = 10 的所有记录。
结果,我的输出应该如下所示:
XYZ,5463.674,93773.683,5734.874,432,-5.683423,-10.38393
AES,7436874.5743,937.6843,8464.5634,564,6.35739,10.6834
PQR,784945.464,57484.8647,57484.453,5764,-10.67484,5.74764
答案1
正如您所暗示的,您可以使用 awk 来实现此目的。您需要定义自己的函数来获取绝对值。所以你可以使用这样的东西:
awk -F, 'function abs(a) {return a < 0 ? -a : a};(abs($6) >= 10 || abs($7) >= 10)' inputfile.txt
XYZ,5463.674,93773.683,5734.874,432,-5.683423,-10.38393
AES,7436874.5743,937.6843,8464.5634,564,6.35739,10.6834
PQR,784945.464,57484.8647,57484.453,5764,-10.67484,5.74764
答案2
您可以尝试使用awk
.类似的东西可以完成这项工作(仅使用内部函数):
awk -F\, '{if (sqrt($(NF-1)*$(NF-1))>=10 || sqrt($NF*$NF)>=10 ) { print $0}}' input_file
答案3
csv
使用可以解析数据和过滤行的工具,例如python
使用csv
module 或csvsql
from csvkit
。
csvsql -H --query 'select * from file where abs(f) > 10 or abs(g) > 10' file | sed 1d
(我通过管道sed
删除输出标题行)。
输出:
XYZ,5463.674,93773.683,5734.874,432.0,-5.683423,-10.38393
AES,7436874.5743,937.6843,8464.5634,564.0,6.35739,10.6834
PQR,784945.464,57484.8647,57484.453,5764.0,-10.67484,5.74764
答案4
使用 Miller ( mlr
) 及其filter
子命令从无标头 CSV 文件中过滤(提取)倒数第二个或最后一个字段的大小为 10 或更大的每条记录:
$ mlr --csv -N filter 'abs($[NF-1]) >= 10 || abs($[NF]) >= 10' file
XYZ,5463.674,93773.683,5734.874,432,-5.683423,-10.38393
AES,7436874.5743,937.6843,8464.5634,564,6.35739,10.6834
PQR,784945.464,57484.8647,57484.453,5764,-10.67484,5.74764
如 中awk
,NF
是当前记录中的字段数。 with$[NF]
我们得到最后一个字段的值,而 while$[NF-1]
给我们倒数第二个字段的值。
如果数据有标题,则可以删除该-N
选项并使用字段名称代替等$[NF]
,例如
mlr --csv filter 'abs($fieldA) >= 10 || abs($fieldB) >= 10' file