![](/img/trans.png)
[英]Make awk print only if matches are greater than 3 and not print if less than 3
[英]compare files awk, print matches and concatenate if there is more than one match
您好我有這兩個文件:
cat file1.tab
1704 1.000000 T G
1708 1.000000 C G
1711 1.000000 G C
1712 0.989011 T A
1712 0.003564 T G
cat file2.tab
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
我想要這個輸出:
1704 1.000000 T G
1705 0
1706 0
1707 0
1708 1.000000 C G
1709 0
1710 0
1711 1.000000 G C
1712 0.003564 T G 0.003564 T G
1713 0
我幾乎可以做到這一點:
awk 'NR==FNR { a[$1]=$0;b[$1]=$1; next} { if ($1 == b[$1]) print a[$1]; else print $1,"0";}' file1.tab file2.tab
但是我不知道如何處理重復。.我的腳本不會檢查file1.tab中第1列中的字符是否重復,因此它只會輸出最后一次出現時的$ 0 ...
您可以使用以下awk:
awk 'FNR==NR{a[$1] = (a[$1]==""?"":a[$1] " ") $2 OFS $3 OFS $4; next}
{print $1, ($1 in a ? a[$1] : 0)}' file1 file2
1704 1.000000 T G
1705 0
1706 0
1707 0
1708 1.000000 C G
1709 0
1710 0
1711 1.000000 G C
1712 0.989011 T A 0.003564 T G
1713 0
參考: 有效的AWK編程 工作原理:
FNR==NR
僅對file1
執行此塊 a[$1] = (a[$1]==""?"":a[$1] " ") $2 OFS $3 OFS $4
創建一個關聯數組a
,鍵為$1
,值為$2 + $3 + $4
(保持附加先前的值) next
-跳到下一個記錄 {...}
-對第二個輸入文件file2
執行此塊 if ($1 in a)
如果$1
中的第2個文件存在於阿雷a
print $1, ($1 in a ? a[$1] : 0
-打印$1
和從陣列如果值$1
在a
否則0
將被打印。 您可以使用如下形式:
$ awk 'NR==FNR{$1=$1 in a?a[$1]:$1;$0=$0;a[$1]=$0;next}{print $1 in a?a[$1]:$1 OFS 0}' file1.tab file2.tab
1704 1.000000 T G
1705 0
1706 0
1707 0
1708 1.000000 C G
1709 0
1710 0
1711 1.000000 G C
1712 0.989011 T A 0.003564 T G
1713 0
一些解釋這是如何工作的:
'NR==FNR{$1=$1 in a?a[$1]:$1;$0=$0;a[$1]=$0;next}
在第一個文件中執行,其中記錄索引等於文件記錄索引。 因此,對於第一個文件,我們將第一個單詞設置為數組中存儲的值(如果存在的話),否則設置為第一個單詞。 然后,使用$0=$0
我們重新分割字段,因為第一個字段現在可能包含多個單詞。 之后,我們將第一個單詞作為索引將行存儲在數組中 {print $1 in a?a[$1]:$1 OFS 0}'
中的行(由於上next
塊中的next
一條語句)。 如果找到匹配的行,則打印它,否則,將0
連接到第一個單詞,然后打印。 與perl
$ perl -F'/\s+/,$_,2' -lane '
if(!$#ARGV){ $h{$F[0]} .= $h{$F[0]} ? " $F[1]" : $F[1] }
else{ print "$F[0] ", $h{$F[0]} ? $h{$F[0]} : 0 }
' file1.tab file2.tab
1704 1.000000 T G
1705 0
1706 0
1707 0
1708 1.000000 C G
1709 0
1710 0
1711 1.000000 G C
1712 0.989011 T A 0.003564 T G
1713 0
-F'/\\s+/,$_,2'
在空白處分割輸入行,最多2個字段 !$#ARGV
對於兩個文件命令行參數將類似於awk的NR==FNR
%h
哈希變量將基於第一個字段的附加值保存為鍵 -l
選項從輸入行中刪除換行符,並將換行符添加到每個print
語句 這是使用join
, uniq
, tac
, grep
和sort
進行的不可阻擋的思考過程的產物。 這樣做的想法是獲取唯一的鍵值對(尤其是鍵1712),並加入它們以避免出現諸如1708 1.000000 CG 1.000000 CG
這樣的行,因此該解決方案將不支持將每個鍵組合成三個或更多的值。 join -o ... -e "0"
也不會在非連接行上僅產生1 0
,因為file1.tab
具有3個要連接的列。
$ join -a 1 <(join -a 1 file2.tab <(uniq -w 4 file1.tab )) <(grep -v -f <(uniq -w 4 file1.tab ) <(tac file1.tab|uniq -w 4|sort))
1704 1.000000 T G
1705
1706
1707
1708 1.000000 C G
1709
1710
1711 1.000000 G C
1712 0.989011 T A 0.003564 T G
1713
更結構化的布局:
$ join -a 1
<(join -a 1
file2.tab
<(uniq -w 4 file1.tab ))
<(grep -v -f
<(uniq -w 4 file1.tab )
<(tac file1.tab|uniq -w 4|sort))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.