【问题标题】:awk how to extract other fields "if duplicates in fields" only if previous fields are the same and above zero仅当先前的字段相同且大于零时,awk如何提取其他字段“如果字段中重复”
【发布时间】:2011-08-04 16:49:39
【问题描述】:

我正在尝试在制表符分隔的文件中查看来自特定字段(第 1 列和第 4 列)重复项的行,并从重复字段块的第一行和最后一行中提取特定列;仅当前面的字段相同且值大于 0 时。例如:

如果两列($1 和 $4)在不同的位置是相同的,并被其他列穿插,需要将它们视为单独的块

示例输入:

  1  tmp1   153446387   153446446   -0.2    1.0888042
  2  tmp1   153446925   153446973   0   0.87891006
  3  tmp1   153451902   153451951   1.43854 1.2709045
  4  tmp1   153454056   153454105   1.43854 1.4132746
  5  tmp1   153456192   153456250   1.43854 0.87553155
  6  tmp1   153458717   153458776   1.335858    1.1829022
  7  tmp1   153460782   153460841   1.335858    0.006651476
  8  tmp1   153462035   153462094   0   0.13484457
  9  tmp1   153463690   153463749   1.43854 0.45511296
 10  tmp1   153467589   153467673   1.43854 1.4431274
 11  tmp1   153467873   153468632   0.31841 1.70443
 12  tmp1   154451904   154451951   1.43854 1.3709045
 13  tmp1   154454054   154454109   1.43854 1.132746
 14  tmp1   154456194   154456259   1.43854 0.8553
 15  tmp2   153472147   153472194   1.43854 0.99288875
 16  tmp2   153476511   153476559   0   0.99288875

输出:

tmp1    153451902   153456250   1.43854
tmp1    153458717   153460841   1.335858
tmp1    153463690   153467673   1.43854
tmp1    154451904   154456259   1.43854
tmp2    153472147   153472194   1.43854

关于如何解决这个问题的任何想法

【问题讨论】:

  • 您的要求我不清楚。为什么,在 field1="tmp1" 和 field4="1.43854" 的第二行块中,您希望在输出中出现两行吗?在这 6 行的块中,在第 2 行之后会发生什么让您想要打印一行输出?请花一点时间清楚地定义您要求我们为您解决的问题。
  • 我刚刚在上面加了行号给你详细解释一下。
  • 您没有回答问题:第 10 行和第 11 行之间发生了什么?
  • 我的错:我现在更正了输入;我的问题是,如果这两列(1 和 4)具有相同的值,则它们的值是否被其他块分开;我希望它们被视为单独的块
  • 那么为什么第 11 行没有出现在您的预期输出中?它的 4 美元大于零。

标签: linux shell scripting awk duplicates


【解决方案1】:
awk '
    BEGIN {OFS = FS = "\t"}
    function output(key, ary) {
        split(key, ary, FS)
        print ary[1], start, end, ary[2]
    }
    $4 <= 0 {next}
    key != $1 FS $4 {
        if (end) {output(key)}
        key = $1 FS $4
        start = $2
    }
    {end = $3}
    END {output(key)}
' filename

【讨论】:

  • 非常感谢;顺便说一句,我如何在每个块中添加行数以及最终开始和结束的差异?
  • @newbiee,在 "key != ..." 块中,将计数初始化为 0,在 "{end = $3}" 块中,增加计数。然后将计数作为参数传递给“输出”函数。
  • 谢谢它的工作;我添加到打印语句计数,结束开始;
  • 如果两列($1 和 $4)在不同的位置是相同的怎么办?它将它们视为我不寻找的同一块?
  • 我们是否需要任何先前和当前的变量与键相关联?或者当它存在当前块时立即打印出来?我非常感谢您的意见...谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-19
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多