提取每一行,然后在第二列中提取具有不同值的行

时间:2016-02-21 11:17:37

标签: bash awk sed extract

鉴于以下文件结构,

SectorRepository

有没有办法提取每一行,其中第二列的值不等于下一行中第二列的值? 即从这三行我想提取第二行,因为1.49不等于1.50。 也许用sed或awk?

这就是我在MATLAB中的表达方式:

9.975   1.49000000      0.295   0       0.4880  0.4929  0.5113  0.5245  2.016726        1.0472  -30.7449        1
9.975   1.49000000      0.295   1       0.4870  0.5056  0.5188  0.5045  2.015859        1.0442  -30.7653        1
9.975   1.50000000      0.295   0       0.5145  0.4984  0.4873  0.5019  2.002143        1.0854  -30.3044        2

但是,我的文件太大了,以至于我希望在将它们传输到我的笔记本电脑之前在终端中进行这种提取。

3 个答案:

答案 0 :(得分:3)

Awk应该这样做。

<data awk '($2 != prev) {print line} {line = $0; prev = $2}'

awk简介:awk程序由一组condition {code}块组成。它逐行运作。如果没有给出条件,则对每一行执行该块。 BEGIN条件在第一行之前执行。每行都分为多个字段,可通过$_number_访问。完整行位于$0

这里我将第二个字段与之前的值进行比较,如果它与前一行的print不匹配。在所有情况下,我将当前行存储到line,将第二个字段存储到prev

如果你真的想要它,小心浮动比较 - 比如abs($2 - prev) < eps(awk中没有abs,你需要自己定义它,而eps是一个足够小的数字)。我实际上不确定awk是否会转换为数字进行相等性测试,如果不是,您可以通过字符串比较来保证安全。

答案 1 :(得分:2)

这可能适合你(GNU sed):

sed -r 'N;/^((\S+)\s+){2}.*\n\S+\s+\2/!P;D' file

一次读两行。前两列上的模式匹配,仅在第二列不匹配时打印第一行。

答案 2 :(得分:1)

尝试以下命令:

awk '$2 != field && field { print line } { field = $2; line = $0 }' infile

它保存上一行和第二个字段,在下一个循环中与当前行值进行比较。 && field检查有助于避免文件开头出现空行,因为$2 != field匹配,因为变量为空。

它产生:

9.975   1.49000000      0.295   1       0.4870  0.5056  0.5188  0.5045  2.015859        1.0442  -30.7653        1