使用 awk 或类似的方法通过特定列中值的差异逐行解析

Posted

技术标签:

【中文标题】使用 awk 或类似的方法通过特定列中值的差异逐行解析【英文标题】:Parse by lines by differences of values in a specific column using awk or something similar 【发布时间】:2018-08-03 17:26:00 【问题描述】:

我有一个包含 5 列的制表符分隔符文件 (file1)。如果第 2 列中的值的差异大于 1 但小于 11,我不想打印行。

这是文件 1:

11 130068214    G   A   Test1
11  133790738   A   C   Test2
11  133790739   A   C   Test2
12  25398281    C   T   Test3
12  25398284    C   T   Test3
12  49418613    C   T   Test4
12  49424177    T   G   Test4
12  49424185    A   C   Test4
12  49434970    T   G   Test4
12  49435227    T   G   Test4
16  2817333 G   T   Test5
16  3781407 T   G   Test6
16  3781413 T   G   Test6
16  3781416 A   C   Test6
16  3781419 A   C   Test6
4   141622708   C   T   Test7
X   107374574   G   A  Test28

这是我想要的输出(file2):

11  130068214   G   A   Test1
11  133790738   A   C   Test2
11  133790739   A   C   Test2
12  49418613    C   T   Test4
12  49434970    T   G   Test4
12  49435227    T   G   Test4
16  2817333 G   T   Test5
4   141622708   C   T   Test7
X   107374574   G   A  Test28

我尝试了以下代码,但没有给我想要的输出:

more file1 | awk 'if ($2!<prev) print $0; prev=$2' > file2

【问题讨论】:

欢迎来到 Stack Overflow,请在您的 POSTS 中为您显示的示例 Input_file 和预期输出使用 CODE TAGS。 【参考方案1】:

您显示的输出不符合您的要求。考虑到您需要前第二列与当前第二列的差异,其差异范围应在 1 到 12 之间,如果是这种情况,那么以下内容可能会对您有所帮助:

awk '((($2-prev)>1) && (($2-prev)<=11)) || FNR==1print prev=$2'  Input_file

【讨论】:

【参考方案2】:

将以下代码保存在一个文件中,比如filter.awk,然后像awk -f filter.awk data.tsv一样运行。

FNR==1  prev = $0; prev_num =$2; prev_ok=1 
FNR>1 
  d = ($2-prev_num)**2; ok = !(d<121 && d>1);
  #workaround for ignoring sign

  if (prev_ok && ok) print(prev);

  prev_num=$2; prev =$0; prev_ok = ok;

END  if (prev_ok)  print (prev); 

【讨论】:

以上是关于使用 awk 或类似的方法通过特定列中值的差异逐行解析的主要内容,如果未能解决你的问题,请参考以下文章

awk

awk命令

awk文本处理

AWK 学习笔记

AWK

awk编辑器