首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >很简单的文件夹里面的全部文本内容合并编程需求但ai给的代码都是错的?

很简单的文件夹里面的全部文本内容合并编程需求但ai给的代码都是错的?

作者头像
生信菜鸟团
发布2025-07-08 17:37:59
发布2025-07-08 17:37:59
4190
举报
文章被收录于专栏:生信菜鸟团生信菜鸟团

有一个转录组测序项目,是2万多个样品,仅仅是fastq文件单个样品就占用5G磁盘,项目总计就是100个T的磁盘消耗。我对它定量就首先需要对fq文件进行质量控制,然后比对成为bam文件,这两个步骤都会翻倍的磁盘消耗。但是我磁盘是有限的,所以只能说是每个样品独立的定量流程然后删除中间的fq和bam文件。因为没有了bam文件的保留,所以这个项目最后每个样品独立的txt格式的表达量矩阵文件。。。。

这个时候,featurecounts软件会在一个文件夹里面的有2万多个文本文件,每个文本文件内容都是固定的,7列,8万行。 需要提取所有的文本文件里面的第7列,然后组成一个矩阵输出即可。

最开始ai给我的是少量文件的解决方案

要使用shell命令从当前文件夹中的所有.txt文件中提取第7列并将它们组成一个矩阵输出,你可以使用awk命令。下面是一个示例命令,它假设你的文本文件是以空格或制表符分隔的:

代码语言:javascript
复制
awk 'BEGIN{FS=OFS="\t"} {for(i=1;i<=NF;i++) if(i==7) printf "%s ", $i; printf "\n"}' *.txt | paste - - - - -

这个命令的解释如下:

  1. awk 'BEGIN{FS=OFS="\t"}:设置字段分隔符(FS)和输出字段分隔符(OFS)为制表符(\t)。这假设你的文件是以制表符分隔的。如果你的文件是以空格分隔的,你可以将FSOFS设置为空格。
  2. {for(i=1;i<=NF;i++) if(i==7) printf "%s ", $i; printf "\n"}:对于每个文件,遍历每一行的每个字段。如果字段编号为7(即第7列),则打印该字段。每行打印完毕后,打印一个换行符。
  3. *.txt:指定处理当前目录下的所有.txt文件。
  4. | paste - - - - -:将awk命令的输出通过管道传递给paste命令,paste命令将多个文件的输出合并成一行。-表示从标准输入读取数据,这里使用了五个-,因为awk命令会为每个文件输出一行。

请注意,这个命令假设你的文本文件的列数至少为7列。如果某些文件的列数少于7列,awk命令将不会打印任何内容。另外如果你的文件是以空格分隔的,你可以将FSOFS设置为空格:

代码语言:javascript
复制
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命令:

代码语言:javascript
复制
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

这个命令的解释如下:

  1. 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:
    • a[NR%5]=NR==1?0:0" ":对于每一行,将内容存储在数组 a中。如果这是第一行(NR==1),则直接存储;否则,在内容后面添加一个空格。
    • 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

代码语言:javascript
复制
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列。

实际上,我想要的是转置的矩阵,就让人工智能大模型继续修改了代码,最后仍然是不得意。。。

后来我一气之下直接去R里面操作了

首先使用简单的cut命令把全部的txt的第7列内容提取后成为一个超级多行的文本文件(但是只有一列):

代码语言:javascript
复制
cut -f 7 *txt  > tmp;gzip tmp;
cut -f 1  `ls *txt|head -1` > gene.id

然后去R里面进行规范化读取:

代码语言:javascript
复制
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或者豆包。但是人人都可以使用人工智能大模型,所以门槛就不再是使用它,而是更好的更高效的使用了!

cat和paste命令针对文本文件分别是按照行和列的合并

在Unix和类Unix系统中,cat(concatenate)和paste命令是常用的文本文件合并工具,它们分别用于按行和按列合并文本文件 :

1. cat命令

cat命令用于按行合并文本文件,即将多个文件的内容连续地显示或写入到一个文件中。这是最基本的文件内容合并方式。

基本用法:

代码语言:javascript
复制
cat file1.txt file2.txt > merged.txt

这个命令将file1.txtfile2.txt的内容合并,并输出到merged.txt文件中。如果省略输出文件,cat会将内容输出到标准输出(通常是终端)。

常用选项:

  • -n--number:给输出的每一行添加行号。
  • -s--squeeze-blank:压缩连续的空白行为一个。
  • -v--show-nonprinting:显示非打印字符。

2. paste命令

paste命令用于按列合并文本文件,即将多个文件的相应行合并为一行,每个文件的内容占据一列。

基本用法:

代码语言:javascript
复制
paste file1.txt file2.txt > merged.txt

这个命令将file1.txtfile2.txt的行按列合并,并输出到merged.txt文件中。每行的列数与输入文件的数量相同。

常用选项:

  • -d--delimiters:指定列之间的分隔符,默认是制表符(\t)。
  • ---serial:逐行读取文件,而不是逐列读取,即按行而不是按列合并文件。

示例

假设有两个文件file1.txtfile2.txt,内容如下:

file1.txt:

代码语言:javascript
复制
1
2
3

file2.txt:

代码语言:javascript
复制
A
B
C

使用paste命令合并这两个文件:

代码语言:javascript
复制
paste file1.txt file2.txt

输出结果:

代码语言:javascript
复制
1   A
2   B
3   C

这显示了如何将两个文件按列合并,每个文件的内容分别占据一列。

总结

  • cat命令适用于按行合并文件,通常用于简单的文件内容拼接。
  • paste命令适用于按列合并文件,通常用于需要将多个文件的相应行合并为一行的场景。

这两个命令在数据处理和文本操作中非常有用,可以根据具体需求选择合适的命令。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-07-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信菜鸟团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 最开始ai给我的是少量文件的解决方案
  • 后来我一气之下直接去R里面操作了
  • 实在是不知道如何借助人工智能大模型来完成这个编程需求
  • cat和paste命令针对文本文件分别是按照行和列的合并
    • 1. cat命令
    • 2. paste命令
    • 示例
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档