帮助bash脚本正确地提取所需的列,并使用filename regex设置正确的标题



我有一个包含多个文件的文件夹。每个文件都有一个命名约定1000T.quant.sf、1000G.quant.sf、1001T.quant.sf、1001G.quant.sf等等。我写的脚本需要用头生成行进行修改。基本上,脚本拉第一列一次,并在所有文件中循环,为目录中的每个文件拉第5列,以生成包含这些列的整体矩阵。我遇到的问题是用正确的替换列标题。我想用每列*.quant.sf之前的字符串替换标题,但目前我有双标题。我该如何解决此问题?

代码段:

cut -f 1 `ls *quant.sf | head -1` > tmp
for x in *quant.sf; do
printf "t" >> tsamples
printf `echo $x | cut -d. -f 1` >> tsamples
cut -f 5 $x | paste tmp - > tmp2
mv tmp2 tmp
done
echo "" >> tsamples
cat tsamples tmp > transcipts.numreads
rm tsamples tmp

电流输出

1001G   1001T   1005G   1005T   1006G
Name    NumReads        NumReads        NumReads        NumReads        NumReads
ENST00000456328.2       12.090  0.000   0.000   0.000   1.545
ENST00000450305.2       0.000   0.000   0.000   0.000   0.000
ENST00000488147.1       620.145 204.533 451.949 250.643 437.618
ENST00000619216.1       0.000   0.000   0.000   0.000   0.000
ENST00000473358.1       0.000   3.680   0.000   1.000   0.000
ENST00000469289.1       4.990   0.000   0.000   0.000   0.000
ENST00000607096.1       0.000   0.000   0.000   0.000   0.000
ENST00000417324.1       0.000   0.000   0.000   0.000   0.000

期望输出:

Name                    1001G   1001T   1005G  1005T    1006G
ENST00000456328.2       12.090  0.000   0.000   0.000   1.545
ENST00000450305.2       0.000   0.000   0.000   0.000   0.000
ENST00000488147.1       620.145 204.533 451.949 250.643 437.618
ENST00000619216.1       0.000   0.000   0.000   0.000   0.000
ENST00000473358.1       0.000   3.680   0.000   1.000   0.000
ENST00000469289.1       4.990   0.000   0.000   0.000   0.000
ENST00000607096.1       0.000   0.000   0.000   0.000   0.000
ENST00000417324.1       0.000   0.000   0.000   0.000   0.000

一个输入文件内容:

$ head 1005T.salmon_quant.sf
Name    Length  EffectiveLength TPM     NumReads
ENST00000456328.2       1657    1441.000        0.000000        0.000
ENST00000450305.2       632     417.000 0.000000        0.000
ENST00000488147.1       1351    1170.738        4.987413        250.643
ENST00000619216.1       68      69.000  0.000000        0.000
ENST00000473358.1       712     512.539 0.045452        1.000
ENST00000469289.1       535     323.000 0.000000        0.000
ENST00000607096.1       138     18.000  0.000000        0.000
ENST00000417324.1       1187    971.000 0.000000        0.000
ENST00000461467.1       590     376.000 0.000000        0.000

使用Name标题初始化tsamples。然后,在处理文件内容时,跳过第一行tail -n +2

printf "Name" >tsamples
tail -n +2 "$(ls *quant.sf | head -1)" | cut -f 1 > tmp
for file in *quant.sf; do
printf 't%s' "${file%%.*}" >> tsamples
tail -n +2 "$file" | cut -f 5 | paste tmp - > tmp2
mv tmp2 tmp
done
echo "" >> tsamples
cat tsamples tmp > transcipts.numreads
rm tsamples tmp

您还可以使用bash的%%参数扩展运算符来删除.中的所有内容,而不是管道到cut

另一个使用关联数组的wariant

#!/bin/bash
header='Namett' # initiate header
declare  -A row   # create associative array 'row' to store rows of data
for file in *.sf; {
header+="t${file%%.*}"   # creating header by appending first part of filename
while read line; do       # read file line by line
[[ $line =~ ame ]] && continue   # skip header
raw=( $line  )        # split line by converting to 'raw' array
name=${raw[0]}        # get name
data=${raw[4]}        # get data
row[$name]+="t$data" # append data to named row
done < $file
};  header+='n' # apend header with new line in the end
printf $header # print header
for key in "${!row[@]}"; {      # print
printf "$key${row[$key]}n" # all
}                               # rows

测试:

$ ./ex 
Name                1005G   1005T
ENST00000607096.1   0.000   4.000
ENST00000450305.2   0.000   3.000
ENST00000473358.1   1.000   1.000
ENST00000417324.1   0.000   0.000
ENST00000619216.1   0.000   3.000
ENST00000456328.2   0.000   1.000
ENST00000461467.1   0.000   0.000
ENST00000488147.1   250.643 230.43
ENST00000469289.1   0.000   0.000

最新更新