Awk 打印超过n行的每个部分

Awk 打印超过n行的每个部分,awk,Awk,我有一个文件重塑的问题,我认为可以用一行程序来完成,但我对sed和awk(还有堆栈溢出)完全是新手。我肯定会失去耐心,在R中使用它,但我认为有这种命令供以后使用可能会很有趣 我有一个带有“集群”的txt文件,如下所示: >Cluster 15425 0 1096aa, >d7719f16-11db-48c4-... * >Cluster 15426 0 1096aa, >fd7eacf9-37cd-4b40-... * 1 436aa, >cfd4b1b

我有一个文件重塑的问题,我认为可以用一行程序来完成,但我对sed和awk(还有堆栈溢出)完全是新手。我肯定会失去耐心,在R中使用它,但我认为有这种命令供以后使用可能会很有趣

我有一个带有“集群”的txt文件,如下所示:

>Cluster 15425
0   1096aa, >d7719f16-11db-48c4-... *
>Cluster 15426
0   1096aa, >fd7eacf9-37cd-4b40-... *
1   436aa, >cfd4b1b0-30df-471e-... at 80.28%
2   413aa, >5992f56b-0269-4add-... at 86.68%
3   395aa, >d3be5814-b2e8-41fe-... at 89.37%
4   239aa, >9e25fbb9-9f6c-4f52-... at 80.33%
>Cluster 15427
0   1096aa, >6c8790d1-5a8b-42d4-... *
>Cluster 15428
0   1096aa, >0c00bc15-51aa-4676-... *
>Cluster 15429
0   1096aa, >1d8ab161-3aab-45a0-... *
>Cluster 15430
0   1096aa, >ef6694d2-a0e6-4bd1-... *
1   410aa, >313eee0a-e8c0-4e8c-... at 84.63%
应该这样读:

15425号集群有一个项目名为>d7719f16-11db-48c4-

14426号集群有5个项目,称为>fd7eacf9-37cd-4b40-…,>CFD4B10B0-30df-471e-。。。etc高达>9e25fbb9-9f6c-4f52-

我想要的是将该文件作为输入,并在另一个文件中吐出包含X个以上项目的所有集群。直观地说,它应该查找以“>”开头的行,并在这两行之间的行数大于X时打印

对于X=1,输出文件应包含:

>Cluster 15426
0   1096aa, >fd7eacf9-37cd-4b40-... *
1   436aa, >cfd4b1b0-30df-471e-... at 80.28%
2   413aa, >5992f56b-0269-4add-... at 86.68%
3   395aa, >d3be5814-b2e8-41fe-... at 89.37%
4   239aa, >9e25fbb9-9f6c-4f52-... at 80.33%
>Cluster 15430
0   1096aa, >ef6694d2-a0e6-4bd1-... *
1   410aa, >313eee0a-e8c0-4e8c-... at 84.63%

(只有编号为15426和15430的集群有多个项目)


谢谢你的帮助

根据显示的样本,您是否可以尝试使用GNU
awk
编写并测试以下内容,在此处读取输入文件2次

awk '
FNR==NR{
  if($0~/^>/){
    ++count
    header[count]=$0
  }
  else{
    a[count]++
    b[count]=(b[count]?b[count] ORS:"")$0
  }
  next
}
/^>/ && a[++count1]>1{
  print header[count1] ORS b[count1]
}
'  Input_file  Input_file
说明:添加上述内容的详细说明

awk '                                           ##Starting awk program from here.
FNR==NR{                                        ##Checking condition FNR==NR which will be TRUE when first time Input_file is being read.
  if($0~/^>/){                                  ##Checking condition if line starts from ^then do following.
    ++count                                     ##Increment 1 with count here.
    header[count]=$0                            ##Creating header array with index of count and its value is current line.
  }
  else{                                         ##mentioning else of above here.
    a[count]++                                  ##Creating array a with index of count and keep increasing its value with 1.
    b[count]=(b[count]?b[count] ORS:"")$0       ##Creating array b with index of count and keep concatenating its values with new line here.
  }
  next                                          ##next will skip all further statements from here.
}
/^>/ && a[++count1]>1{                          ##Checking condition if line starts from > AND value of array a with index of count1 is greater than 1 then do following.
  print header[count1] ORS b[count1]            ##Printing header with index count1 and array b with index of count1 here.
}
'  Input_file Input_file                        ##Mentioning Input_file names here.

根据显示的样本,请您尝试以下内容,在GNU
awk
中编写和测试,在此处读取输入文件2次

awk '
FNR==NR{
  if($0~/^>/){
    ++count
    header[count]=$0
  }
  else{
    a[count]++
    b[count]=(b[count]?b[count] ORS:"")$0
  }
  next
}
/^>/ && a[++count1]>1{
  print header[count1] ORS b[count1]
}
'  Input_file  Input_file
说明:添加上述内容的详细说明

awk '                                           ##Starting awk program from here.
FNR==NR{                                        ##Checking condition FNR==NR which will be TRUE when first time Input_file is being read.
  if($0~/^>/){                                  ##Checking condition if line starts from ^then do following.
    ++count                                     ##Increment 1 with count here.
    header[count]=$0                            ##Creating header array with index of count and its value is current line.
  }
  else{                                         ##mentioning else of above here.
    a[count]++                                  ##Creating array a with index of count and keep increasing its value with 1.
    b[count]=(b[count]?b[count] ORS:"")$0       ##Creating array b with index of count and keep concatenating its values with new line here.
  }
  next                                          ##next will skip all further statements from here.
}
/^>/ && a[++count1]>1{                          ##Checking condition if line starts from > AND value of array a with index of count1 is greater than 1 then do following.
  print header[count1] ORS b[count1]            ##Printing header with index count1 and array b with index of count1 here.
}
'  Input_file Input_file                        ##Mentioning Input_file names here.

您没有提供任何脚本,因此我不会提供完整的答案,但我可以给您一个开始:为了计算文件的行数,您可以使用
wc-l

wc -l file.txt
12 file.txt
grep <something> file.txt | wc -l
3
您可以使用
awk
仅获取结果的第一部分(行数)

如果您对行数感兴趣,并遵循特定条件,则可以使用
grep
wc-l
的组合:

wc -l file.txt
12 file.txt
grep <something> file.txt | wc -l
3
grep file.txt | wc-l
3.
(很明显,在file.txt中有三次


这为您的脚本提供了一个良好的开端。

您没有提供任何脚本,因此我不会向您提供完整的答案,但我可以给您一个开端:为了计算文件的行数,您可以使用
wc-l

wc -l file.txt
12 file.txt
grep <something> file.txt | wc -l
3
您可以使用
awk
仅获取结果的第一部分(行数)

如果您对行数感兴趣,并遵循特定条件,则可以使用
grep
wc-l
的组合:

wc -l file.txt
12 file.txt
grep <something> file.txt | wc -l
3
grep file.txt | wc-l
3.
(很明显,在file.txt中有三次


这为您的脚本提供了一个良好的开端。

以下
perl
解决方案有效

perl -ne '
    BEGIN { $N = 1 }
    if (/^>/) {
        print @b if @b > $N+1;
        @b = ();
    }
    push @b, $_;
    END {
        print @b if @b > $N+1
    }' input_file
使用相同方法的
awk
解决方案:

awk '
    BEGIN { N = 1 }
    /^>/ {
        if (nb>N+1) for (i=0; i<nb; i++) print b[i];
        nb = 0; delete b;
    }
    { b[nb++]= $0; }
    END {
        if (nb>N+1) for (i=0; i<nb; i++) print b[i];
    }' input_file
awk'
开始{N=1}
/^>/ {

如果(nb>N+1)for(i=0;iN+1)for(i=0;i以下
perl
解决方案有效

perl -ne '
    BEGIN { $N = 1 }
    if (/^>/) {
        print @b if @b > $N+1;
        @b = ();
    }
    push @b, $_;
    END {
        print @b if @b > $N+1
    }' input_file
使用相同方法的
awk
解决方案:

awk '
    BEGIN { N = 1 }
    /^>/ {
        if (nb>N+1) for (i=0; i<nb; i++) print b[i];
        nb = 0; delete b;
    }
    { b[nb++]= $0; }
    END {
        if (nb>N+1) for (i=0; i<nb; i++) print b[i];
    }' input_file
awk'
开始{N=1}
/^>/ {
如果(nb>N+1)for(i=0;iN+1)for(i=0;i


另一种
awk
,需要多字符支持(例如gawk)

它可以简化

$ awk -F'\n' -v RS='\n>' 'NF>2{print ">" $0}' file

请注意,在第一个选项的开头和第二个选项的结尾有一个额外的新行。

另一个
awk
,需要多字符支持(例如gawk)

它可以简化

$ awk -F'\n' -v RS='\n>' 'NF>2{print ">" $0}' file

请注意,在第一个选项的开头和第二个选项的结尾有一个额外的新行。

欢迎使用SO,抱歉,您的问题不清楚。请您在问题中添加更多详细信息,说明获取输出文件的条件是什么?您需要的是一个输出文件还是多个文件tput?请编辑您的问题,然后让我们知道。@RavinderSingh13谢谢您的评论,我编辑了这篇文章。我只想要一个文件作为输出,它的格式与输入文件类似,但没有大小为1的集群。我也很难找到这篇文章的名称,如果您有更好的想法,我会很高兴。我很难表达这一点sue可能是我在google上找不到任何帮助的原因。想到有人会认为R是更简单的解决方案,有点滑稽。欢迎这么说,抱歉,但你的问题不清楚。你能在你的问题中添加更多细节吗?你想获得输出文件的条件是什么?还有,是1个输出文件还是多个文件你需要输出吗?请编辑你的问题,然后让我们知道。@RavinderSingh13谢谢你的评论,我编辑了这篇文章。我只想要一个文件作为输出,它的格式与输入文件类似,但没有大小为1的簇。我也很难找到这篇文章的名称,如果你有更好的想法,我会很高兴的。我很难做到这一点最近这个问题可能是我在谷歌上找不到任何帮助的原因。想到有人会认为R是更简单的解决方案,有点滑稽。谢谢!!我知道这种命令可能存在,我将把它保存在我的“magic commands”文件中:)稍后我将尝试解析它。如果将文件中的最后一个块更改为1行而不是2行,则脚本仍将输出它,就好像它满足“多行”条件一样。我想将
RS
更改为
\n(>|$)
将修复它,它确实解决了这个问题,但是它在输出中引入了另一个问题,没有终止
\n
。谢谢!!我知道这种命令可能存在,我将把它保存在我的“magic commands”文件中:)稍后我将尝试解析它。如果将文件中的最后一个块更改为1行而不是2行,则脚本仍将输出它,就好像它满足“多行”条件一样。我想将
RS
更改为
\n(>|$)
将修复该问题,并且确实解决了该问题,但随后在输出中引入了另一个没有终止的问题
\n