如何编写 for 循环来合并 bash 中所有文件的第 n 列

Ano*_*non 5 bash awk sed

在代码的第二行中,我尝试按*.out.tab列合并所有文件。代码的第三行提取第一列和每4 个后续列(第 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
Run Code Online (Sandbox Code Playgroud)

但是,现在我想使用 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
Run Code Online (Sandbox Code Playgroud)

输入示例:

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
Run Code Online (Sandbox Code Playgroud)

期望的输出:

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
Run Code Online (Sandbox Code Playgroud)

Rav*_*h13 5

根据您显示的示例和尝试,请尝试以下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
Run Code Online (Sandbox Code Playgroud)

说明:为上述代码添加详细说明。

  • 使用索引presence为 $1 的数组并检查它的出现是否不存在,然后在其中创建一个条目,然后:
  • 创建一个arr以变量索引命名的数组max,其值不断增加,并将值赋值为arr$1。
  • 开始for循环遍历每行中的每 4 个、第 8 个、第 12 个和每 4 个字段。
  • 创建一个maxValue以索引 of命名的数组$1,并在此处仅保留 MAX 值 仅通过使用三元运算符检查条件。
  • 创建一个名为的数组,overAllMax该数组将具有所有相似的第一个字段,所有最大值都会附加到它,以基本上获得总体最大值。
  • END该程序的块中,通过从1到 直到 valuemax来打印所有值。
  • 内部循环打印 的值arr[j](即$1),其值为overAllMax[arr[j]]所有文件中每个 $1 的最大值。