我有两个简单的文本文件:
第一个参考文件看起来像这样 - 每一行的第一个字母都是重要的一个。
G A
C A
G A
第二个看起来像这样:
G G G G
A A A A
A A A G
第二个文件是我想要根据第一个文件的信息更改的文件。
例如,如果前两列包含字母G,即G G
,因为此字母是我的参考文件中的第一个字母,我想将这两个列转换为带有该数字的单个列2
(表示有两个G)。第三列和第四列也有两个G
,因此我想将这两列也转换为数字为2
的单个列。
在第二个文件的最后一行中,前两列的字母为A
和A
,但因为我的参考文件最后一行的第一个字母是{{1}我想将这两列转换为数字0(表示零G
- 参考文件的第一个字母是我正在计算的那个字母)。第三列和第四列有一个G
和一个A
,因为有一个G
,我希望将这两列转换为一个数字为1的列。
转换后的文件应如下所示:
G
任何帮助将不胜感激。一次处理两个文件并进行此类转换不在我的编程技能范围内。
注意:我的真实文件包含字母A,C,G和T
答案 0 :(得分:0)
假设第一个文件名为ref
,第二个文件名为data
:
$ awk 'NR==FNR{a[FNR]=$1; next} {print (a[FNR]==$1)+(a[FNR]==$2), (a[FNR]==$3)+(a[FNR]==$4)}' ref data
2 2
0 0
0 1
说明:
NR==FNR{a[FNR]=$1; next}
NR
是到目前为止已读取的行数,FNR
是到目前为止从当前文件读取的行数。因此,当NR==FNR
时,我们知道awk
仍在处理第一个文件。在这种情况下,我们将第一个字母保存在数组a
中的行上。 next
语句告诉awk
跳过其余命令并转到下一行。
print (a[FNR]==$1)+(a[FNR]==$2), (a[FNR]==$3)+(a[FNR]==$4)
由于上面的next
命令,只有在我们处理第二个文件时才会执行此命令。如果是这样,我们打印出前两列中有多少字母与ref
文件中相应行的第一个字母匹配,然后对第三列和第四列执行相同操作。
假设0 0
表示缺失数据。例如,获取此数据文件:
$ cat data2
G G G G
0 0 C A
A G 0 0
以下awk脚本已扩展为显示“?”数据丢失的地方:
$ awk 'NR==FNR{a[FNR]=$1; next} {print ($1==0)?"?":(a[FNR]==$1)+(a[FNR]==$2), ($3==0)?"?":(a[FNR]==$3)+(a[FNR]==$4)}' ref data2
2 2
? 1
1 ?
(与以前一样使用了相同的ref
文件。)
awk 'NR==FNR{a[FNR]=$1; next} {s="";for (i=1;i<NF;i=i+2) {s=s OFS (($i==0)?"?":((a[FNR]==$i)+(a[FNR]==$(i+1))))}; print s}' ref3 data3