【问题标题】:Compare curent line and next line in awk比较 awk 中的当前行和下一行
【发布时间】:2021-03-29 07:31:25
【问题描述】:

我想找到这样的模式:当前行中的第 2 列是“C”,下一行中的第 2 列是“G”。文件的第4列是'CG'。我想比较第 1 到第 2、第 3 到第 4、第 5 到第 6,依此类推。然后打印几行当前行和下一行。 'C' 可以出现在偶数行和奇数行中。

这样输入:

chr1    C   10467   CHH CT  0.0 0   1
chr1    C   10469   CG  CG  0.0 0   1
chr1    G   10470   CG  CG  0.0 0   8
chr1    C   10471   CG  CG  0.0 0   1
chr1    G   10472   CG  CG  1.0 8   8

预期输出是,由制表符分隔:

chr1    C   10469   CG  CG  0.0 0   1
chr1    G   10470   CG  CG  0.0 0   8
chr1    C   10471   CG  CG  0.0 0   1
chr1    G   10472   CG  CG  1.0 8   8

我的代码是:

awk '{a=$2; c=$4; d=$0; e=NR; getline; f=$2; g=$4} {if (a == "C" && f == "G" && c == "CG" && g == "CG") {print d,e,"\n",$0,NR}}' input_file

我使用 getline 并检查下一行是否有“G”。问题是,如果我这样做,awk 将直接转到第三行,并且会错过一些行。 例如,输入的第 2 列是:

Line 1: G
Line 2: C
Line 3: G
Line 4: C

预期的输出是第 2 行和第 3 行。但是,awk 直接从第一行转到第三行,而不是逐行。所以,输出是无。

亲切的问候!

【问题讨论】:

  • 文件的第 4 列是 'CG' 对于这两个记录还是只是后者?
  • 嗨,James,第 4 列是两条记录的“CG”。
  • 换个思路:比较当前行和上一行。

标签: awk


【解决方案1】:

编辑(将每一行与下一行进行比较,使用这一行):现在添加这个解决方案,以及 OP 的新示例。

awk '
FNR>1{
  if(secCol=="C" && $2=="G" && fourthCol=="CG" && $4=="CG"){
    print prevLine ORS $0
  }
}
{
  secCol=$2
  fourthCol=$4
  prevLine=$0
}
'  Input_file

说明:为上述添加详细说明。

awk '
##Starting awk program from here.
FNR>1{
##Checking condition if current line number is more than 1 then do following.
  if(secCol=="C" && $2=="G" && fourthCol=="CG" && $4=="CG"){
##Checking condition if secCol is C AND 2nd column is G AND fourthCol is CG and 4th column is CG then do following. 
    print prevLine ORS $0
##Printing prevLine ORS and current line.
  }
}
{
  secCol=$2
##Creating secCol with 2nd column of current line.
  fourthCol=$4
##Creating fourthCol with 4th column of current line.
  prevLine=$0
##Setting prevLine to current line value.
}
'  Input_file ##Mentioning Input_file name here. 


初始解决方案(比较每个奇数行和偶数行):(OP 的示例在编辑后变得更加清晰,但也将这个解决方案保留在这里以供未来的读者阅读,以备不时之需) 请您尝试以下,仅按照所示示例编写。这会检查上一行是否有第 4 列(fourthCol)是否也是 CG,以防您不需要它,然后从以下内容中删除 && foruthCol=="CG"

awk '
FNR%2==0{
  if(secCol=="C" && $2=="G" && fourthCol=="CG" && $4=="CG"){
    print prevLine ORS $0
  }
  prevLine=secCol=fourthCol=""
  next
}
{
  secCol=$2
  fourthCol=$4
  prevLine=$0
}
'  Input_file

输出如下。

chr1    C   10469   CG  CG  0.0 0   1
chr1    G   10470   CG  CG  0.0 0   8
chr1    C   10471   CG  CG  0.0 0   1
chr1    G   10472   CG  CG  1.0 8   8

说明:为上述添加详细说明。

awk '                          ##Starting awk program from here.
FNR%2==0{                      ##Checking condition if line number is divided by 2 or not.
  if(secCol=="C" && $2=="G" && fourthCol=="CG" && $4=="CG"){
##Checking condition if secCol is C AND 2nd column is G AND fourthCol is CG and 4th column is CG then do following.
    print prevLine ORS $0      ##Printing prevLine ORS and current line.
  }
  prevLine=secCol=fourthCol="" ##Nullifying prevLone, secCol, fourthCol here.
  next                         ##next will skip all further statements from here.
}
{
  secCol=$2                    ##Creating secCol with 2nd column of current line.
  fourthCol=$4                 ##Creating fourthCol with 4th column of current line.
  prevLine=$0                  ##Setting prevLine to current line value.
}
'  Input_file                  ##Mentioning Input_file name here. 

【讨论】:

  • @RavinderSingh13 谢谢。就我而言,此代码缺少一些输出,例如我的代码。 FNR%2=0 是偶数行,此代码与 'C' 一起出现在奇数行。当'C'出现在偶数行时,此代码将丢失一些输出。你可以试试这个输入:chr1 C 10467 CHH CT 0.0 0 1 chr1 C 10469 CG CG 0.0 0 1 chr1 G 10470 CG CG 0.0 0 8 chr1 C 10471 CG CG 0.0 0 1 chr1 G 10472 CG CG 1.0 8 8
  • @bobia9193,您能否在此处使用这些详细信息更新您的问题,以便更好地理解。你想像这样比较1st to 2nd, 3rd to 4th, 5th to 6th吗?还是像1st to 2nd, 2nd to 3rd, 3rd to 4th之类的线路?请确认一次。
  • 感谢您的帮助!就像我在詹姆斯解决方案中的评论一样:我是这个领域的新手,所以我想问你一些问题以加深理解。这个awk的结构是什么?那里是否有条件,BEGIN,END?你能解释一下关于 awk 结构的代码吗?再次感谢!
  • @bobia9193,我现在为我的 EDIT 解决方案添加了详细说明,它应该对您有所帮助。如需更多了解awk,请查看stackoverflow.com/tags/awk/info 链接,干杯。
【解决方案2】:

伙计,我首先理解完全错误。希望这次我做对了。

$ awk '
$2=="G" && $4=="CG" && p2=="C" && p4=="CG" {
    print p ORS $0
}
{
    p=$0
    p2=$2
    p4=$4
}' file

输出:

chr1    C   10469   CG  CG  0.0 0   1
chr1    G   10470   CG  CG  0.0 0   8 
chr1    C   10471   CG  CG  0.0 0   1
chr1    G   10472   CG  CG  1.0 8   8

解释:

awk '
$2=="G" &&            # the column 2 in current line is G
$4=="CG" &&           # And the column 4 of file is CG
p2=="C" &&            # the column 2 is C in a previous line
p4=="CG" {            # And the column 4 of file is CG
    print p ORS $0    # Then print a couple of current line and next line
}
{
    p=$0              # current record is previous on next round
    p2=$2             # same goes for column 2
    p4=$4             # and column 4
}' file

【讨论】:

  • Sr,我是这个领域的新手,所以我想问一些问题。这个awk的结构是什么?那里有条件吗?你能解释一下关于 awk 结构的代码吗?
  • 引用 AWK 编程语言每个 awk 程序 - - 是一个或多个模式动作语句的序列:pattern { action } awk 的基本操作是依次扫描一系列输入行,在程序中搜索 任何模式 [if] 匹配的行。 - - 对于每个匹配的模式,执行相应的操作 [then] - - 。
  • 所以,这个解决方案的开头可以写成:{ if ($2=="G" && $4=="CG" && p2=="C" && p4=="CG") print p ORS $0 }.
猜你喜欢
  • 1970-01-01
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 2014-10-30
  • 1970-01-01
  • 2023-02-06
  • 1970-01-01
相关资源
最近更新 更多