在代码的第二行中,我试图按列合并所有*.out.tab
文件。代码的第三行提取第一列和随后的每一列(第4列、第8列、第12列、第16列…),即每个文件的每四列。
如果没有for循环,它就像。。。
paste 1.out.tab 2.out.tab 3.out.tab 4.out.tab
awk '{for(i=1;i<=NF;i+=4){printf "%s ",$i;} print ""}' |
tail -n +5 > tmpfile
cat tmpfile | sed "s/^ENSG*//" >gene_count.txt
但是,现在我想使用for循环来合并所有文件。
for f in `./alignments/repaired_reads/*ReadsPerGene.out.tab | sed 's/.ReadsPerGene.out.tab//'`;
paste "$f".out.tab |
awk '{for(i=1;i<=NF;i+=4){printf "%s ",$i;} print ""}' |
tail -n +5 > tmpfile
cat tmpfile | sed "s/^ENSG*://" > gene_count.txt
样本输入:
head ./alignments/repaired_reads/SRR9200814ReadsPerGene.out.tab
N_unmapped 18517 18517 18517
N_multimapping 1620 1620 1620
N_noFeature 8046 33145 33275
N_ambiguous 5860 1201 1034
ENSG00000160072 0 0 0
ENSG00000279928 0 0 0
ENSG00000228037 0 0 0
ENSG00000142611 0 0 0
ENSG00000284616 0 0 0
ENSG00000157911 0 0 0
head ./alignments/repaired_reads/SRR9200815ReadsPerGene.out.tab
N_unmapped 124416 124416 124416
N_multimapping 19165 19165 19165
N_noFeature 40924 384454 392595
N_ambiguous 99220 21834 20712
ENSG00000160072 0 0 0
ENSG00000279928 0 0 0
ENSG00000228037 0 0 0
ENSG00000142611 35 22 13
ENSG00000284616 0 0 0
ENSG00000157911 24 22 8
期望输出:
N_unmapped 18517 124416
N_multimapping 1620 19165
N_noFeature 33275 392595
N_ambiguous 1034 20712
ENSG00000160072 0 0
ENSG00000279928 0 0
ENSG00000228037 0 0
ENSG00000142611 0 13
ENSG00000284616 0 0
ENSG00000157911 0 8
使用您显示的示例和尝试,请尝试以下awk
代码。这将确保$1的订单(第一个字段)与他们的存在相同。这将创建名为gene_count.txt
的输出文件,并将读取多个文件作为输入。
awk '
!presence[$1]++{
arr[++max]=$1
}
{
for(i=4;i<=NF;i+=4){
maxValue[$1]=(maxValue[$1]>$i?maxValue[$1]:$i)
}
overAllMax[$1]=(overAllMax[$1]?overAllMax[$1] OFS:"") maxValue[$1]
}
END{
for(j=1;j<=max;j++){
print arr[j],overAllMax[arr[j]]
}
}
' *ReadsPerGene.out.tab > gene_count.txt
解释:添加对上述代码的详细解释。
- 使用一个名为
presence
、索引为$1的数组,并检查其是否不存在,然后在其中创建一个条目,然后: - 创建一个名为
arr
的数组,该数组的索引为max
变量,其值递增,并将值分配给arr
作为$1 - 开始
for
循环,每行每4、8、12和每4个字段一次 - 创建一个名为
maxValue
的数组,索引为$1
,并在此仅保留MAX值。仅通过使用三元运算符检查条件 - 创建一个名为
overAllMax
的数组,它将有所有类似的第一个字段,所有的最大值都会不断附加到它后面,以基本上获得整体的最大值 - 在该程序的
END
块中,从1
一直到max
的值,打印所有值 arr[j]
的内循环打印值(即$1
)和overAllMax[arr[j]]
的值(即所有文件的每$1的最大值)
假设:
- 根据第一列的内容连接多个文件
- 所有文件在第一列中都有相同的行数和相同的值集
一种awk
方法:
awk '
FNR==NR { lines[++max]=$1 } # lines[] used to maintain ordering of input rows (based on first file)
{ for (i=4;i<=NF;i+=4) # loop through 4th, 8th, 12th, ... columns
rec[$1]= rec[$1] (rec[$1]=="" ? "" : OFS) $i # append to the record for this particular 1st column
}
END { for (i=1;i<=max;i++) # loop through indices of lines[] array
print lines[i],rec[lines[i]] # print 1st column and associated rec[] entry
}
' ./alignments/repaired_reads/*ReadsPerGene.out.tab > gene_count.txt
注意:
lines[]
数组的唯一用途是允许我们维护输入行的顺序(从第一个文件开始)- OP的当前
sed
脚本从第一列的开头删除了ENSG
字符串,但这并没有反映在预期输出中;现在我将忽略此操作
这会生成:
$ cat gene_count.txt
N_unmapped 18517 124416
N_multimapping 1620 19165
N_noFeature 33275 392595
N_ambiguous 1034 20712
ENSG00000160072 0 0
ENSG00000279928 0 0
ENSG00000228037 0 0
ENSG00000142611 0 13
ENSG00000284616 0 0
ENSG00000157911 0 8
这可能对你有用(GNU sed):
sed -E 's/^(S+)(s+(S+))*/1 3/
H
x
s/((nS+) [^n]*)((n[^n]*)*)2([^n]*)$/153/
x
$!d
x
s/.//' *.out.tab
将每行缩减为第一列和最后一列。
将当前行附加到保留空间。
切换到保留空间。
将先前复制的行的最后一列附加到其匹配行,并连接第一列。
切换回图案空间。
删除除最后一行以外的所有行。
在最后一行交换到保留空间。
删除第一个字符(这是H
命令引入的换行符)。
打印结果。