有一个转录组测序项目,是2万多个样品,仅仅是fastq文件单个样品就占用5G磁盘,项目总计就是100个T的磁盘消耗。我对它定量就首先需要对fq文件进行质量控制,然后比对成为bam文件,这两个步骤都会翻倍的磁盘消耗。但是我磁盘是有限的,所以只能说是每个样品独立的定量流程然后删除中间的fq和bam文件。因为没有了bam文件的保留,所以这个项目最后每个样品独立的txt格式的表达量矩阵文件。。。。
这个时候,featurecounts软件会在一个文件夹里面的有2万多个文本文件,每个文本文件内容都是固定的,7列,8万行。 需要提取所有的文本文件里面的第7列,然后组成一个矩阵输出即可。
要使用shell命令从当前文件夹中的所有.txt文件中提取第7列并将它们组成一个矩阵输出,你可以使用awk命令。下面是一个示例命令,它假设你的文本文件是以空格或制表符分隔的:
awk 'BEGIN{FS=OFS="\t"} {for(i=1;i<=NF;i++) if(i==7) printf "%s ", $i; printf "\n"}' *.txt | paste - - - - -
这个命令的解释如下:
awk 'BEGIN{FS=OFS="\t"}:设置字段分隔符(FS)和输出字段分隔符(OFS)为制表符(\t)。这假设你的文件是以制表符分隔的。如果你的文件是以空格分隔的,你可以将FS和OFS设置为空格。{for(i=1;i<=NF;i++) if(i==7) printf "%s ", $i; printf "\n"}:对于每个文件,遍历每一行的每个字段。如果字段编号为7(即第7列),则打印该字段。每行打印完毕后,打印一个换行符。*.txt:指定处理当前目录下的所有.txt文件。| paste - - - - -:将awk命令的输出通过管道传递给paste命令,paste命令将多个文件的输出合并成一行。-表示从标准输入读取数据,这里使用了五个-,因为awk命令会为每个文件输出一行。请注意,这个命令假设你的文本文件的列数至少为7列。如果某些文件的列数少于7列,awk命令将不会打印任何内容。另外如果你的文件是以空格分隔的,你可以将FS和OFS设置为空格:
awk 'BEGIN{FS=OFS=" "} {for(i=1;i<=NF;i++) if(i==7) printf "%s ", $i; printf "\n"}' *.txt | paste - - - - -
这将设置字段分隔符和输出字段分隔符为空格。
我纠正后,重新说了我的需求是多个文件的合并,不仅仅是三五个。然后人工智能大模型给我一个更夸张的解决方案:就是不停地加上短横线作为占位符!

上短横线作为占位符
这我肯定是不满意啊,我试图给人工智能大模型一个简单的问题让它帮我写代码。因为我可以很容易把全部的txt文件合并然后提取第7列即可。唯一的麻烦就是这个时候并不是一个矩阵格式:
一个文本文件里面有100行,但是只有一列,现在想读取它然后每5行内容成为一个行,这样的话就有5列,20行。使用shell代码
要实现这个需求,你可以使用 awk命令来处理文本文件,将每5行的内容合并成一行,形成5列。以下是一个示例的shell命令:
awk '{a[NR%5]=NR==1?$0:$0" "; if(NR%5==0||NR==FNR){for(i=1;i<=5;i++) printf "%s", a[i]; print ""; a=()} }' *.txt
这个命令的解释如下:
if(NR%5==0||NR==FNR):检查是否已经处理了5行或者已经处理完所有行(FNR是当前文件的记录数)。for(i=1;i<=5;i++) printf "%s", a[i]:遍历数组 a的前5个元素,并将它们打印出来。print "":打印一个换行符,以便开始新的一行。a=():清空数组 a,以便处理下一组5行。这个命令会处理当前目录下的所有 .txt文件,并将每5行的内容合并成一行,形成5列。如果你只想处理一个特定的文件,可以替换 *.txt为文件名,例如 file.txt:
awk '{a[NR%5]=NR==1?$0:$0" "; if(NR%5==0||NR==FNR){for(i=1;i<=5;i++) printf "%s", a[i]; print ""; a=()} }' file.txt
这样,你就可以将一个文本文件中的内容每5行合并成一行,形成5列。
实际上,我想要的是转置的矩阵,就让人工智能大模型继续修改了代码,最后仍然是不得意。。。
首先使用简单的cut命令把全部的txt的第7列内容提取后成为一个超级多行的文本文件(但是只有一列):
cut -f 7 *txt > tmp;gzip tmp;
cut -f 1 `ls *txt|head -1` > gene.id
然后去R里面进行规范化读取:
library(stringr)
library(rio)
d1<-data.table::fread("./inputs/tmp.gz",header = F,
data.table = F)
id=read.table('inputs/gene.id',header = F)[,1];head(id)
n=nrow(d1)/(length(id)+1);n
tmp = do.call(cbind,
lapply(1:n, function(i){
start=(i-1)*((length(id)+1))
return(d1[(start+1):(start+((length(id)+1))),])
}))
tmp=tmp[-1,]
sid=gsub('3.hisat2/','', gsub('.sort.bam','',tmp[1,]) )
tmp=tmp[-1,]
colnames(tmp) = sid
tmp[1:4,1:4]
mat = apply(tmp,2,as.numeric)
dim(mat)
mat[1:4,1:4]
rownames(mat) = id[-1]
keep_feature <- rowSums (mat > 1) > 1 ;table(keep_feature)
ensembl_matrix <- mat[keep_feature, ]
rownames(ensembl_matrix)=rownames(mat)[keep_feature]
ensembl_matrix[1:4,1:4]
ct=ensembl_matrix
rownames(ct)=gsub('[.][0-9]*','',rownames(ct))
library(AnnoProbe)
head(rownames(ct))
ids=annoGene(rownames(ct),'ENSEMBL','human')
head(ids)
tail(sort(table(ids$biotypes)))
ids=ids[ids$biotypes=='protein_coding',]
ct=ct[rownames(ct) %in% ids$ENSEMBL,]
ct[1:4,1:4]
rownames(ct)=ids$SYMBOL[match(rownames(ct),ids$ENSEMBL)]
ct[1:4,1:4]
symbol_matrix = as.data.frame(ct)
人工智能大模型已经出来了两三年了,大家应该是或多或少都开始用起来了。早期需要费大劲的chatGPT,现在也有了了各个国内的互联网大厂平替的kimi或者豆包。但是人人都可以使用人工智能大模型,所以门槛就不再是使用它,而是更好的更高效的使用了!
在Unix和类Unix系统中,cat(concatenate)和paste命令是常用的文本文件合并工具,它们分别用于按行和按列合并文本文件 :
cat命令cat命令用于按行合并文本文件,即将多个文件的内容连续地显示或写入到一个文件中。这是最基本的文件内容合并方式。
基本用法:
cat file1.txt file2.txt > merged.txt
这个命令将file1.txt和file2.txt的内容合并,并输出到merged.txt文件中。如果省略输出文件,cat会将内容输出到标准输出(通常是终端)。
常用选项:
-n或 --number:给输出的每一行添加行号。-s或 --squeeze-blank:压缩连续的空白行为一个。-v或 --show-nonprinting:显示非打印字符。paste命令paste命令用于按列合并文本文件,即将多个文件的相应行合并为一行,每个文件的内容占据一列。
基本用法:
paste file1.txt file2.txt > merged.txt
这个命令将file1.txt和file2.txt的行按列合并,并输出到merged.txt文件中。每行的列数与输入文件的数量相同。
常用选项:
-d或 --delimiters:指定列之间的分隔符,默认是制表符(\t)。-或 --serial:逐行读取文件,而不是逐列读取,即按行而不是按列合并文件。假设有两个文件file1.txt和file2.txt,内容如下:
file1.txt:
1
2
3
file2.txt:
A
B
C
使用paste命令合并这两个文件:
paste file1.txt file2.txt
输出结果:
1 A
2 B
3 C
这显示了如何将两个文件按列合并,每个文件的内容分别占据一列。
cat命令适用于按行合并文件,通常用于简单的文件内容拼接。paste命令适用于按列合并文件,通常用于需要将多个文件的相应行合并为一行的场景。这两个命令在数据处理和文本操作中非常有用,可以根据具体需求选择合适的命令。