我有两个文件,File_1包含I,File_2包含要匹配的数据。每个文件如下所示:
File_1
Cluster 43
Cluster 51
Cluster 145
Cluster 160
File_2
>Cluster 43
0 5249nt, >CL276.Contig2_All... at +/98.55%
1 6413nt, >CL276.Contig3_All... *
2 5375nt, >CL276.Contig5_All... at +/95.91%
3 5405nt, >CL276.Contig6_All... at +/98.33%
>Cluster 51
0 6298nt, >CL5173.Contig2_All... *
1 3421nt, >CL5173.Contig3_All... at +/99.50%
2 1017nt, >CL5173.Contig4_All... at +/98.13%
3 503nt, >Unigene10077_All... at +/98.01%
>Cluster 145
0 4772nt, >CL1798.Contig5_All... at +/98.49%
1 4782nt, >CL1798.Contig8_All... *
2 4781nt, >CL1798.Contig10_All... at +/99.27%
3 4773nt, >CL1798.Contig11_All... at +/99.25%
>Cluster 160
0 2883nt, >CL4790.Contig2_All... at +/95.87%
1 4699nt, >CL4790.Contig3_All... *
2 1274nt, >CL4790.Contig7_All... at +/99.37%
3 4616nt, >CL4790.Contig14_All... at -/95.65%我需要在File_2中找到与File_1中的in匹配的所有行,并打印匹配的行(如“集群43”),并在单独的字段中打印匹配字符串之间的所有行。所需的输出应该如下所示
Cluster 43 5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
Cluster 51 6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All使用我的逗号行(见下文),我可以处理文件,根据来自File_2的ID在File_1中获得匹配的行,打印匹配的行和匹配之间的所有行,并从每一行中删除所有不想要的信息,但是,我在找到一个解决方案来在一个单独的字段中打印匹配的匹配行时遇到了问题,如上面所示的期望输出中所示。
我的命令行
$ grep -A4 -Fwf File_1 File_2 | sed 's/All.*//g;/Contig/s/.$/_All/g;/Unigene/s/.$/_All/g;s/-.*//;/^$/d;s/.//;s/[,>]//g' | awk '{print $1, $2}' > my_wanted_file结果输出
$head my_wanted_file
Cluster 43
5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
Cluster 51
6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All为了实现我的目标,我编写了以下命令行:
$ awk '/^Cluster/ {if ('\n') {printf NR==4}}' my_wanted_file | head但它什么也没印。
然后我试着:
$ awk '/Cluster/ {for(i=1; i<=4; i++) {getline; print}}' my_wanted_file | head但是它只连续地打印每个匹配(集群)之间的行,如下所示
5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All
4772nt CL1798.Contig5_All
4782nt CL1798.Contig8_All我找不到路要走
Cluster 43
5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
Cluster 51
6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All到这个
Cluster 43 5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
Cluster 51 6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All我非常感谢在这方面提供一点帮助。
发布于 2019-12-05 15:54:02
你能试一下吗。虽然我不确定您是否需要值直到All或字符串at之前,或者All是否真的出现在您的Input_file中,因此我们也可以相应地更改正则表达式。
这也将为所有行提供相等的空间。
awk '
FNR==NR{
$0=">"$0
a[$0]
max=max>length($0)?max:length($0)
next
}
FNR==1 && FNR!=NR{
spaces=sprintf("%-"max+1"s",OFS)
}
/^>/{
found=val=count=""
}
/^>/ && $0 in a{
found=1
val= $0
remain_spaces=sprintf("%-"max-length($0)+1"s",OFS)
next
}
found{
gsub(/^>|at.*/,"",$3)
sub(/,/,"",$2)
printf("%s\n",++count==1?val remain_spaces $2 OFS $3:spaces $2 OFS $3)
}
' Input_file1 Input_file2输出如下。
>Cluster 43 5249nt CL276.Contig2_All...
6413nt CL276.Contig3_All...
5375nt CL276.Contig5_All...
5405nt CL276.Contig6_All...
>Cluster 51 6298nt CL5173.Contig2_All...
3421nt CL5173.Contig3_All...
1017nt CL5173.Contig4_All...
503nt Unigene10077_All...
>Cluster 145 4772nt CL1798.Contig5_All...
4782nt CL1798.Contig8_All...
4781nt CL1798.Contig10_All...
4773nt CL1798.Contig11_All...
>Cluster 160 2883nt CL4790.Contig2_All...
4699nt CL4790.Contig3_All...
1274nt CL4790.Contig7_All...
4616nt CL4790.Contig14_All...发布于 2019-12-05 16:28:00
这就是你想要做的(使用GNU awk来表示多个字符的RS、ENDFILE和\s ( [[:space:]]) )吗?
$ cat tst.awk
NR==FNR {
tgts[$0]
next
}
ENDFILE {
RS = "(^|\n)(>|$)"
FS = "\n"
}
(FNR > 1) && ($1 in tgts) {
gsub(/\n[0-9]+\s+/,"\n")
gsub(/[,>]|[.]{3}[^\n]*/,"")
for (i=2; i<=NF; i++) {
print $1, $i
gsub(/./," ",$1)
}
}。
$ awk -f tst.awk File_1 File_2
Cluster 43 5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
Cluster 51 6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All
Cluster 145 4772nt CL1798.Contig5_All
4782nt CL1798.Contig8_All
4781nt CL1798.Contig10_All
4773nt CL1798.Contig11_All
Cluster 160 2883nt CL4790.Contig2_All
4699nt CL4790.Contig3_All
1274nt CL4790.Contig7_All
4616nt CL4790.Contig14_All发布于 2019-12-05 16:29:46
假设输入是:
Cluster 43
5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
Cluster 51
6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All假设每个集群都有5行代码,则可以执行以下操作:
sed 'N;s/[[:blank:]]*\n[[:blank:]]*/|/; n;s/^/|/; n;s/^/|/; n;s/^/|/'或者像这样,看起来更短,不知道是不是更好:
sed 's/^/|/' | sed 's/^|//;N;s/\n//;N;N;N'得到:
Cluster 43|5249nt CL276.Contig2_All
|6413nt CL276.Contig3_All
|5375nt CL276.Contig5_All
|5405nt CL276.Contig6_All
Cluster 51|6298nt CL5173.Contig2_All
|3421nt CL5173.Contig3_All
|1017nt CL5173.Contig4_All
|503nt Unigene10077_All您可以选择其他分隔符,然后选择|。现在您可以通过column运行它来对其进行列列:
column -t -s '|' -o ' '将产生以下结果:
Cluster 43 5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
Cluster 51 6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All我测试它的整个命令如下所示:
cat <<EOF |
Cluster 43
5249nt CL276.Contig2_All
6413nt CL276.Contig3_All
5375nt CL276.Contig5_All
5405nt CL276.Contig6_All
Cluster 51
6298nt CL5173.Contig2_All
3421nt CL5173.Contig3_All
1017nt CL5173.Contig4_All
503nt Unigene10077_All
EOF
sed 'N;s/[[:blank:]]*\n[[:blank:]]*/|/; n;s/^/|/; n;s/^/|/; n;s/^/|/' | column -t -s '|' -o ' 'https://stackoverflow.com/questions/59197966
复制相似问题