过滤文件以查找在一列中匹配但在另一列中不同的行
Filter a file to find rows that match in one column but differ in another column
我想过滤一个文件,以便我可以获得在第 1 列中匹配但在第 2 列中不匹配的行。在以下示例中:
00b27c71-a833-4605-9fb3-a2714ac98092 ENST00000352983.6 157 60 16
00d77e65-466e-4fe6-ad0f-bc6b3f44af75 ENST00000367142.4 130 12 4
00d77e65-466e-4fe6-ad0f-bc6b3f44af75 ENST00000367142.4 8 60 0
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000367142.5 130 12 4
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000367142.7 8 60 0
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000258424.2 8 60 0
我想在第 1 列中找到恰好出现两次但在第 2 列中不匹配的整体,即应忽略组合 column1、column2 中的重复项。所以预期的输出将是:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
第 3、4、5 等列中的内容对于过滤并不重要,但我确实需要保留这些信息。
我还需要从读取文件和保留 header 所必需的另一个输出中导入它。所以我需要以下格式的内容:
samtools view -h file.bam | code that I need > results.bam
我试过好几个版本的awk,都没有用。任何帮助将不胜感激。
编辑: 根据 OP,它应该从 awk
中单独读取,所以添加它 not.w
your_command | awk '
{
a[]++;
b[ FS ]++;
c[ FS ]=[=10=]
}
END{
for(i in a){
for(j in b){
split(j,array," ");
if(a[i]==2 && b[j]==1 && i==array[1]){ print c[j] }
}
}}'
能否请您尝试关注,如果对您有帮助,请告诉我。
awk 'FNR==NR{a[]++;b[ FS ]++;next} a[]==2 && b[ FS ]==1' Input_file Input_file
我相信你追求的是:
awk '!( FS in a) { b[]++; a[ FS ]=[=10=] }
END { for(i in a) {[=10=]=i; if (b[]==2) print a[i] } }' file
这输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
它本质上做的是检查组合 FS
是否在数组 a
中。如果不是,请跟踪 b[]
中 </code> 的计数并将整行存储在 <code>a[ FS ]
中。最后,如果计数正确,则打印 a[i]
。备注 b
的密钥是通过将密钥 i
重新分配给 [=24=]
获得的。这将重新定义字段 </code> 和 <code>
并且 </code> 是您想要的键。</p>
<p><strong>注意:</strong>上面的脚本不一定会跟踪顺序,因为数组遍历是以未指定的顺序完成的。如果你想保持顺序,你需要跟踪行索引:</p>
<pre><code>awk '!( FS in a) { b[]++; a[ FS ]=[=12=]; c[NR]= FS }
END { for(i=1;i<=NR;++i) if(i in c) { [=12=]=c[i]; if (b[]==2) print a[[=12=]]}
}' file
输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
旧答案:
awk '!( in a) { a[]=; b[]=[=14=]; next }
!match(,a[]){a[]=a[] FS ; b[]=b[] ORS [=14=]}
END { for (i in a) if (gsub(FS,FS,a[i]) == 1) print b[i] }' file
这输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
它本质上做的是跟踪两个数组(a
和 b
),这两个数组都由第一列索引。如果数组 a
不包含列 </code> 的元素,则将其添加到字符串 <code>a[]
。它还将整行存储在 b[]
中,由 ORS
分隔。
最后我们统计a[i]
中有多少个字段,如果是两个就打印b[i]
.
我想过滤一个文件,以便我可以获得在第 1 列中匹配但在第 2 列中不匹配的行。在以下示例中:
00b27c71-a833-4605-9fb3-a2714ac98092 ENST00000352983.6 157 60 16
00d77e65-466e-4fe6-ad0f-bc6b3f44af75 ENST00000367142.4 130 12 4
00d77e65-466e-4fe6-ad0f-bc6b3f44af75 ENST00000367142.4 8 60 0
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000367142.5 130 12 4
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000367142.7 8 60 0
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000258424.2 8 60 0
我想在第 1 列中找到恰好出现两次但在第 2 列中不匹配的整体,即应忽略组合 column1、column2 中的重复项。所以预期的输出将是:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
第 3、4、5 等列中的内容对于过滤并不重要,但我确实需要保留这些信息。
我还需要从读取文件和保留 header 所必需的另一个输出中导入它。所以我需要以下格式的内容:
samtools view -h file.bam | code that I need > results.bam
我试过好几个版本的awk,都没有用。任何帮助将不胜感激。
编辑: 根据 OP,它应该从 awk
中单独读取,所以添加它 not.w
your_command | awk '
{
a[]++;
b[ FS ]++;
c[ FS ]=[=10=]
}
END{
for(i in a){
for(j in b){
split(j,array," ");
if(a[i]==2 && b[j]==1 && i==array[1]){ print c[j] }
}
}}'
能否请您尝试关注,如果对您有帮助,请告诉我。
awk 'FNR==NR{a[]++;b[ FS ]++;next} a[]==2 && b[ FS ]==1' Input_file Input_file
我相信你追求的是:
awk '!( FS in a) { b[]++; a[ FS ]=[=10=] }
END { for(i in a) {[=10=]=i; if (b[]==2) print a[i] } }' file
这输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
它本质上做的是检查组合 FS
是否在数组 a
中。如果不是,请跟踪 b[]
中 </code> 的计数并将整行存储在 <code>a[ FS ]
中。最后,如果计数正确,则打印 a[i]
。备注 b
的密钥是通过将密钥 i
重新分配给 [=24=]
获得的。这将重新定义字段 </code> 和 <code>
并且 </code> 是您想要的键。</p>
<p><strong>注意:</strong>上面的脚本不一定会跟踪顺序,因为数组遍历是以未指定的顺序完成的。如果你想保持顺序,你需要跟踪行索引:</p>
<pre><code>awk '!( FS in a) { b[]++; a[ FS ]=[=12=]; c[NR]= FS }
END { for(i=1;i<=NR;++i) if(i in c) { [=12=]=c[i]; if (b[]==2) print a[[=12=]]}
}' file
输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
旧答案:
awk '!( in a) { a[]=; b[]=[=14=]; next }
!match(,a[]){a[]=a[] FS ; b[]=b[] ORS [=14=]}
END { for (i in a) if (gsub(FS,FS,a[i]) == 1) print b[i] }' file
这输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
它本质上做的是跟踪两个数组(a
和 b
),这两个数组都由第一列索引。如果数组 a
不包含列 </code> 的元素,则将其添加到字符串 <code>a[]
。它还将整行存储在 b[]
中,由 ORS
分隔。
最后我们统计a[i]
中有多少个字段,如果是两个就打印b[i]
.