我有一个包含 11 列数据的文件,每列之间用空格分隔。对于第 2 列中的每一行,我需要在第 9 列中找到最接近的值。因此,下面将采用第 2 列中的第一个条目 (0.01) 并在第 9 列中找到最接近的值(第 3 行中的 0.009)。
文件布局:
x 0.01 x x x x x x 0.002 x x
x 0.034 x x x x x x 0.0045 x x
x 0.002 x x x x x x 0.009 z z
x 0.002 x x x x x x 0.0021 x x
x 0.015 x x x x x x 0.0031 x x
当前代码:
awk '{
if (sqrt(($2)^2-($9)^2)<0.0001)
print "Particle ID "$1" is within 2D of wall"
}' filename
我认为这有两个问题:
1)这并不比较每个排列,只是比较列中的每一行
2)它只检查它们是否在某个范围内,而不是最接近的。
所需的输出将是一个新文件,类似于
x 0.01 x x x x x x 0.009 z z
对于所有其他线路依此类推
答案1
使用awk
宏TXR 口齿不清:
$ txr closest.tl < data
x 0.01 x x x x x x 0.009 x x
x 0.034 x x x x x x 0.009 x x
x 0.002 x x x x x x 0.0021 z z
x 0.002 x x x x x x 0.0021 x x
x 0.015 x x x x x x 0.009 x x
代码在closest.tl
:
(build
(awk
((fconv - r : : r - -) (add f))
(:end (let ((fs (get)))
(each ((f fs))
(let ((min (find-min fs : (op abs (- [f 1] [@1 8])))))
(set [f 8] [min 8])
(prn . f)))))))
build
创建一个用于按程序构造隐式列表的环境。在 包含的代码中build
,我们用于(add ...)
将项目添加到隐式列表并(get)
检索该列表。在环境内部
build
,我们有一个宏的实例awk
。该宏具有一条条件动作规则和一条:end
规则。在条件-动作规则中,我们有一个(fconv ...)
表达式作为条件。这是无条件正确的,因此我们匹配每条记录。将fconv
选定字段转换为浮点(r
=“实数”)。该操作的意思是(add f)
:将当前字段列表添加到隐式列表中。因此,我们将数据构建为行列表,即字段列表。fconv
之所以需要,是因为 TXR Lisp 是一种强类型语言。该awk
宏实现了 Awk 的许多语义,但没有实现我们可以将字符串视为"3.14"
数字的鸭子类型。当数据结束时,
:end
子句触发awk
,这就是我们进行最近距离处理的地方。我们将行放入一个名为 的变量中,并为每行fs
迭代一个变量。f
对于每一行,我们从 中找到最小项fs
,其中该项是所检查的每一行中该行的字段 1 和字段 8 之间的差的绝对值。当我们找到最小距离行时,我们将该行的字段 8 替换为该最小距离行的字段 8。请注意,字段从 0 开始编号:
[f 0]
,[f 1]
, ... 与 Awk 不同,没有约定零字段是整个记录;整个记录称为rec
.将字段替换
[f 8]
为最小距离字段后,我们打印字段。