如何将多个关联文件的行连接成一行,并将其附加到输出文件

如何将多个关联文件的行连接成一行,并将其附加到输出文件

我有几个文件命名BC**-tmp1.tsv为爆炸输出的第一次迭代,其他文件命名BC**-tmp2.tsv为第二次迭代。

文件示例BC02-tmp1.tsv(分隔符\t:):

BC02    Aaa 2712    94  0   99.073  2053209 CP023507.1  1597    A
BC02    Bbb 2712    94  0   99.073  2053209 CP023507.1  1597    B
BC02    Ccc 2712    94  0   99.073  2053209 CP023507.1  1597    C
BC02    Ddd 2712    94  0   99.073  2053209 CP023507.1  1597    D

文件示例BC02-tmp2.tsv(分隔符\t:):

BC02    Eee 2712    94  0   99.073  2053209 CP023507.1  1597    E
BC02    Fff 2712    94  0   99.073  2053209 CP023507.1  1597    F
BC02    Ggg 2712    94  0   99.073  2053209 CP023507.1  1597    G
BC02    Hhh 2712    94  0   99.073  2053209 CP023507.1  1597    H

我的目标是以特定方式将所有这些文件成对(迭代 1 + 迭代 2)连接起来。

BC02结果示例与最终文件中的示例:

BC02    Aaa 2712    94  0   99.073  2053209 CP023507.1  1597    A   B   C   BC02    Eee 2712    94  0   99.073  2053209 CP023507.1  1597    E   F   G

因此,更准确地说,我想打印(在同一行上)文件的第一行BC**-tmp1.tsv,然后是第二行的最后一列,然后是第三行的最后一列,然后是文件的第一行BC**-tmp2.tsv,然后是第二行的最后一列,然后是第三行的最后一列。每对条形码也是如此。

笔记:第二个迭代文件并不总是存在。

到目前为止,我设法在 shellfor循环中收集相关文件,但我不知道如何执行其余操作:

touch template.tsv

for bla in *-tmp1.tsv; do
r="$(basename -s "-tmp1.tsv" $bla)"
awk 'FNR==1' $bla >> template.tsv
awk 'FNR==1' $r-tmp2.tsv >> template.tsv;
done

你知道怎么做吗 ?


编辑更简单的输入/输出:

输入:

$ head BC02-tmp*.tsv
==> BC02-tmp1.tsv <==
a       b       B
a       c       C
a       d       D
a       e       E

==> BC02-tmp2.tsv <==
a       w       W
a       x       X
a       y       Y
a       z       Z

输出:

a       b       B       C       D       a       w       W       X       Y

答案1

假设您的输入不包含边缘情况,则与程序连接的以下 shell 循环awk应该执行以下操作:

for f in BC*-tmp1.tsv
do
    f2="${f/%tmp1.tsv/tmp2.tsv}"
    if [[ ! -f $f2 ]]; then f2=""; fi
    awk 'BEGIN{FS=OFS="\t"}
         FNR==1{for (i=1;i<NF;i++) printf "%s%s",(NR==FNR&&i==1?"":OFS),$i}
         FNR<=3{printf "%s%s",OFS,$NF}
         END{printf "%s",ORS}' "$f" "$f2" >> template.tsv
done

这将循环遍历所有tmp1.tsv文件并生成该tmp2.tsv文件相应的文件名。如果第二个文件不存在,则文件名将设置为空字符串。

然后它将调用一个awk具有两个关联 TSV 文件的程序,该程序将打印 - 全部在同一行

  • 每个输入文件第一行的所有字段(不包括最后一个字段)(但在第二个输入文件的情况下,前面有一个附加 OFS,其特征为FNR,每个文件行计数器,不再等于NR,全局行柜台),
  • 每行的最后一个字段直到第 3 行,
  • 当没有输入文件剩余时,结束记录分隔符(默认为换行符)

并将输出附加到template.tsv.如果第二个模板文件不存在,这也将起作用,因为空字符串标记awk首先不会被识别为输入文件,因此END打印换行符的部分将在第一个文件之后到达。

相关内容