根据使用 awk 对当前行和前一行字段进行简单数学运算的结果来打印或遗漏字符串

根据使用 awk 对当前行和前一行字段进行简单数学运算的结果来打印或遗漏字符串
1529.89 1.05    22.36   48.78   33.8
1529.91 2.05    22.36   52.79   36.93
1529.92 3.06    22.36   52.80   36.93
1529.92 4.25    22.36   52.79   36.94
1529.92 5.10    22.36   52.79   36.94
1529.93 5.24    22.36   52.80   36.94
1529.94 6.05    22.36   52.80   36.94
1529.95 6.27    22.36   52.80   36.94
1529.95 7.01    22.36   52.80   36.94
1529.96 7.26    22.36   52.80   36.94
1529.97 8.11    22.36   52.80   36.94
1529.99 9.22    22.35   52.80   36.94
1530.00 10.12   22.36   52.80   36.94
1530.02 11.26   22.36   52.80   36.94
1530.03 12.18   22.36   52.80   36.94
1530.04 13.12   22.36   52.81   36.94
1530.06 14.04   22.36   52.81   36.95
1530.10 16.21   22.36   52.81   36.94
1530.11 17.17   22.35   52.80   36.94
1530.12 18.09   22.35   52.81   36.94
1530.14 19.19   22.35   52.81   36.94
1530.15 20.19   22.35   52.80   36.94
1530.17 21.24   22.35   52.81   36.94
1530.18 22.05   22.35   52.81   36.95
1530.20 23.14   22.35   52.81   36.95
1530.21 24.14   22.35   52.81   36.94
1530.23 25.23   22.35   52.80   36.94
1530.23 26.03   22.35   52.80   36.94
1530.23 26.24   22.34   52.80   36.94
1530.26 27.10   22.35   52.81   36.95

我有这种类型的文件。我需要的是,如果第二个字段中的整数不等于前一行第二个字段中的相同数字,则打印它的每一行,例如下面两行:

1529.94 6.05    22.36   52.80   36.94
1529.95 6.27    22.36   52.80   36.94

...我想只打印第一行并跳过第二行。第二个字段编号增加到约 1300,然后减少到 1。

我尝试使用 awk substr() 函数,但它似乎不起作用,因为我卡住了:

awk -F. '{for (i=NR;i<3814;i++) {i=1 n=(substr($2,4))}{i=i+1 v=(substr($2,4))} {if ((n+v)%2=1) print $0} {i++}}' test.csv

答案1

抱歉,你的awk回答完全没有帮助,它与你表达的要求完全不同。

  • 您的字段分隔符可能不是“.”但空间
  • 解析您不需要的十进制数substr()
  • 将小数舍入为整数,只需int()

所以代码看起来像这样:

awk 'int($2)!=prev{
  print
  prev=int($2)
}'

要使其成为一行,您需要一个“;”

awk 'int($2)!=prev{print;prev=int($2)}'

结果是:

1529.89 1.05    22.36   48.78   33.8
1529.91 2.05    22.36   52.79   36.93  
1529.92 3.06    22.36   52.80   36.93
1529.92 4.25    22.36   52.79   36.94
1529.92 5.10    22.36   52.79   36.94
1529.94 6.05    22.36   52.80   36.94
1529.95 7.01    22.36   52.80   36.94
1529.97 8.11    22.36   52.80   36.94
1529.99 9.22    22.35   52.80   36.94
1530.00 10.12   22.36   52.80   36.94
1530.02 11.26   22.36   52.80   36.94
1530.03 12.18   22.36   52.80   36.94
1530.04 13.12   22.36   52.81   36.94
1530.06 14.04   22.36   52.81   36.95
1530.10 16.21   22.36   52.81   36.94
1530.11 17.17   22.35   52.80   36.94
1530.12 18.09   22.35   52.81   36.94
1530.14 19.19   22.35   52.81   36.94
1530.15 20.19   22.35   52.80   36.94
1530.17 21.24   22.35   52.81   36.94
1530.18 22.05   22.35   52.81   36.95
1530.20 23.14   22.35   52.81   36.95
1530.21 24.14   22.35   52.81   36.94
1530.23 25.23   22.35   52.80   36.94
1530.23 26.03   22.35   52.80   36.94
1530.26 27.10   22.35   52.81   36.95

正确的 ?

答案2

如果您不介意使用sed

sed -E '1p;N;/^[^ ]+ +([0-9]+)\..*\n[^ ]+ +\1\./D;h;s/.*\n//p;x;$d;D' test.csv

使用该N;P;D模式,您总是同时处理两行。长正则表达式是在第二个字段中找到整数相同的两行,然后继续下一行,否则打印第二行并继续。根据要求提供更详细的解释。

如果您的字段分隔符是制表符而不是空格,只需调整模式即可。

答案3

使用(以前称为 Perl_6):第二个示例

raku -e 'my @a = lines.rotor(2 => -1); for @a {.[0].put if .words[1].Int != .words[6].Int};'    

或者

raku -e 'my @a = lines.rotor(2 => -1); for @a -> $a {$a.[0].say when $a.words[1].Int != $a.words[6].Int };' 

上面的 Raku 代码是对 OP 标题的相当字面的解释。使用 来连接成对的线rotor,创建重叠,使得线0,1成对、1,2成对、2,3成对等。对于@a包含成对线的数组的每个位置,执行条件测试Int第二列的 eger 等价性。如果Ints 不相等,则配对行的第一个元素(行)为 out- put

这种方法的一个警告是rotor默认情况下仅返回完全“分组”的元素。因此,任何尾随的“元素簇”都会从@a数组中删除。问题的标题是“...当前行和前一行的字段之间的简单数学计算...”,但这个答案强制严格配对(最后一行是未配对的)。希望这个答案在任何情况下都有用。

示例输出:

1529.89 1.05    22.36   48.78   33.8
1529.91 2.05    22.36   52.79   36.93
1529.92 3.06    22.36   52.80   36.93
1529.92 4.25    22.36   52.79   36.94
1529.93 5.24    22.36   52.80   36.94
1529.95 6.27    22.36   52.80   36.94
1529.96 7.26    22.36   52.80   36.94
1529.97 8.11    22.36   52.80   36.94
1529.99 9.22    22.35   52.80   36.94
1530.00 10.12   22.36   52.80   36.94
1530.02 11.26   22.36   52.80   36.94
1530.03 12.18   22.36   52.80   36.94
1530.04 13.12   22.36   52.81   36.94
1530.06 14.04   22.36   52.81   36.95
1530.10 16.21   22.36   52.81   36.94
1530.11 17.17   22.35   52.80   36.94
1530.12 18.09   22.35   52.81   36.94
1530.14 19.19   22.35   52.81   36.94
1530.15 20.19   22.35   52.80   36.94
1530.17 21.24   22.35   52.81   36.94
1530.18 22.05   22.35   52.81   36.95
1530.20 23.14   22.35   52.81   36.95
1530.21 24.14   22.35   52.81   36.94
1530.23 25.23   22.35   52.80   36.94
1530.23 26.24   22.34   52.80   36.94

https://raku.org

答案4

使用(以前称为 Perl_6)

raku -e 'my @a = lines.map(*.words); my %seen; for @a[*].map(*.[1].Int) {   \
         %seen.=append: ( $_ => $++ ) }; for %seen.values.map(*.min).sort -> $a {  \
         @a[$a].join("\t").put };' 

或者

raku -e 'my @a = lines>>.words;  my @b = @a.map(*.[1].Int).pairs.unique( :as(*.value) ); \
         @b.=map(*.key); for @b -> $a {@a[$a].join("\t").put};'

简而言之,lines被单独分解成单词,并存储在@a数组中。

(上面的第一个例子):%seen声明了一个散列。对于每行的第二列,它被转换为Int,并且每个都成为使用粗箭头语法的Int键/值对,其中as 键和零索引行号为。这些键/值对被附加到哈希中。由于哈希的键必须是唯一的,因此多个行号会添加到同一个键中。最后,通过迭代哈希值并提取行号,并将其用作位置索引来仅打印数组的匹配行,从而输出数据。=>Intvalue%seenIntput%seenvaluesmin$a@a[$a]@a

上面的第二个示例:每行的第一列被转换为Int,并且这些进一步被转换为pairs,其中行号作为键和Int值。pairs然后将它们unique在此基础上进行比较:as(*.value)。然后通过用每个数组元素单独覆盖@b数组来恢复行号。这些s 如上所述用于索引行数组。@b.=map(*.key)keykey@a

示例输出:

1529.89 1.05    22.36   48.78   33.8
1529.91 2.05    22.36   52.79   36.93
1529.92 3.06    22.36   52.80   36.93
1529.92 4.25    22.36   52.79   36.94
1529.92 5.10    22.36   52.79   36.94
1529.94 6.05    22.36   52.80   36.94
1529.95 7.01    22.36   52.80   36.94
1529.97 8.11    22.36   52.80   36.94
1529.99 9.22    22.35   52.80   36.94
1530.00 10.12   22.36   52.80   36.94
1530.02 11.26   22.36   52.80   36.94
1530.03 12.18   22.36   52.80   36.94
1530.04 13.12   22.36   52.81   36.94
1530.06 14.04   22.36   52.81   36.95
1530.10 16.21   22.36   52.81   36.94
1530.11 17.17   22.35   52.80   36.94
1530.12 18.09   22.35   52.81   36.94
1530.14 19.19   22.35   52.81   36.94
1530.15 20.19   22.35   52.80   36.94
1530.17 21.24   22.35   52.81   36.94
1530.18 22.05   22.35   52.81   36.95
1530.20 23.14   22.35   52.81   36.95
1530.21 24.14   22.35   52.81   36.94
1530.23 25.23   22.35   52.80   36.94
1530.23 26.03   22.35   52.80   36.94
1530.26 27.10   22.35   52.81   36.95

https://raku.org

相关内容