Shell-Script

如何將多個關聯文件的行連接成一行,並將其附加到輸出文件

  • September 22, 2021

我有幾個文件命名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

假設您的輸入不包含邊緣情況,則與awk程序相關的以下 shell 循環應該執行以下操作:

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列印換行符的部分將在第一個文件之後到達。

引用自:https://unix.stackexchange.com/questions/669976