从目录文件中提取特定列到新文件中

时间:2019-11-30 02:44:01

标签: python shell awk

我有一个11064个文件的集合,它们都有相同的文件扩展名ReadsPerGene.out.tab。它们在目录中。所有文件都有556行4列。

Filenames look like this:
SRR123.ReadsPerGene.out.tab
SRR456.ReadsPerGene.out.tab
SRR555.ReadsPerGene.out.tab
DRR789.ReadsPerGene.out.tab
...

File looks like this:
for SRR123ReadsPerGene.out.tab        for SRR789.ReadsPerGene.out.tab
A    45   67   78                       A    89O  90   34
B    17   40   23                       B    129  96   45
C    27   50   19                       C     60  56   91
...  ...  ...  ...                     ...   ...  ...  ...                                           

首先,我要判断所有文件的第一列是否相同。

如果是真的,我想创建一个具有665行,11065列的output.txt文件。第一列是每个文件的第一列(因为它们相同)。而output.txt的11065列中的第二列是每个输入文件的第二列,我想将特定的文件名添加为每一列的第一行。

The output.txt looks like this:

      SRR123                SRR789              SRR456        ...
A        45                 89O                66            ...
B        17                 129                480           ...
C        27                  60                78            ...
...      ...               ...               ...             ...

以下是我的答案。 **
** 1。获取所有文件名

#!/bin/bash
cd ~
filepath=/home/shared/maize/bam_rsem
cd ${filepath}
for file in $(ls *.ReadsPerGene.out.tab)
do
   echo $file >> ~/filename.txt
done

2。 在一个文件中获取所有第一列

#!/bin/bash
cd ~
OUT=result2.txt
touch $OUT
filepath=/home/shared/maize/bam_rsem/
for file in $(cat filename.txt)
do
   filePATH=`echo ${filepath}$file`
   cut -f 1 $filePATH | sed 1i\ ${file} >$OUT.tmp1
   paste $OUT $OUT.tmp1 >$OUT.tmp
   rm $OUT.tmp1
   mv $OUT.tmp $OUT
done

3。 比较第一列是否与result2.txt中的其他列相同
我现在不知道。
4. 创建output.txt

#!/bin/bash
cd ~
OUT=result2.txt
touch $OUT
filepath=/home/shared/maize/bam_rsem/
for file in $(cat filename.txt)
do
   filePATH=`echo ${filepath}$file`
   cut -f 1 $filePATH | sed 1i\ ${file} >$OUT.tmp1
   paste $OUT $OUT.tmp1 >$OUT.tmp
   rm $OUT.tmp1
   mv $OUT.tmp $OUT
done

cut -f 1 result2.txt >$OUT.tmp2
paste $OUT.tmp2 $OUT >$OUT.tmp3
rm $OUT.tmp2
mv $OUT.tmp3 $OUT

我应该为我的脚本做什么?在Linux中执行我的脚本确实很慢。 还是应该编写一个Python脚本来处理它,但是我从未学习过python或Perl,而我对Linux却只有一点了解。

我很抱歉我的英语不好,我无法及时回复。无论如何,感谢您的所有回答!

2 个答案:

答案 0 :(得分:2)

awk中的一个。要处理的文件名位于files中(由于文件名过多):

$ cat files
SRR123.ReadsPerGene.out.tab
SRR789.ReadsPerGene.out.tab

awk程序将与数据文件一起在目录中运行(split头文件名的文件名的第一个.分隔部分,即前导路径会使头文件名很冗长):

$ awk '
BEGIN{OFS="\t"}
{
    files[NR]=$0                                # hash filenames from file files
}
END{
    for(i=1;i<=NR;i++) {                        # loop files
        nr=0
        split(files[i],t,".")
        h[nr]=h[nr] OFS t[1]                    # build header
        while((getline < files[i])>0) {         # using getline to read data records
            nr++                                # d[++nr] order not same in all awks
            d[nr]=d[nr] OFS $2                  # append data fields to previous
            if(i==1) {                          # get headers from first file
                h[(refnr=nr)]=$1
            } else if($1!=h[nr]) {              # check that they stay the same
                print "Nonmatching field name"
                exit                            # or exit without output
            }
        }
        if(nr!=refnr) {                         # also record count must be the same
            print "Nonmatching record count"
            exit
        }
        close(files[i])
    }
    for(i=0;i<=refnr;i++)                       # output part
        print h[i] d[i]
}' files

输出:

        SRR123  SRR789
A       45      89O
B       17      129
C       27      60
...     ...     ...

[++nr] order not same in all awks :显然有些awks更喜欢d[++nr]=d[nr] OFS $2和一些d[nr]=d[++nr] OFS $2,所以单独的nr++两者都适用。

更新

如果文件位于不同的路径中,并且文件files中的文件名不包含路径,请智能替换:

split(files[i],t,".")
...
while((getline < files[i])>0) {

file="home/shared/maize/bam_rsem/" files[i]
split(file,t,".")
...
while((getline < file)>0) {

AND

close(files[i])

close(file)

答案 1 :(得分:0)

尝试一下,让我知道它是否在此答案的评论部分中起作用。

import pandas as pd
import glob

files = sorted(glob.glob("*.log.out", recursive=False))

#dropped_col_1 = list()
#kept_col_2 = list()
drop_files = dict()
keep_files = dict()
ref_file_name = 'SRR123.log.out'
df_ref_file = pd.read_csv(ref_file_name, sep='\t', header=None)
for i, filename in enumerate(files):
    df_file = pd.read_csv(filename, sep='\t', header=None)
    if df_ref_file['0'] != df_file['0']:
        drop_files.update({filename: df_file['0'].tolist()})
        #dropped_col_1.append(df_file['0'].tolist())
    else:
        keep_files.update({filename: df_file['1'].tolist()})        
        #kept_col_2.append(df_file['1'].tolist())

df = pd.DataFrame(keep_files, index=df_ref_file['0'])
df.index.names = ['ID']
df.reset_index(inplace=True)
# check the shape of the dataframe
df.shape
相关问题