shell或python脚本批量处理txt文件

有一堆小文本文件,格式为:文件名.m8,其实就是txt文本文件。文件内,一行内容为一条信息,信息内容用tab隔开。

SRR329659.m8文件内容:

SRR329659.5585.1    XXXX    44.8    29    16    14    100    527    555    6.0e-07    35.4    VRRNFPHCMVFAYMDDVVLGAKSVEHLES    GTCCAAAGAGCCTTTCCCTCATGTCTTATATATCACTATATGGACGACATTCTCCTAGCCCATCCCAAACCAGAACAACTTGATTCA
SRR329659.40047.1    XXXX    39.3    28    17    87    4    529    556    5.1e-06    32.3    RNFPHCMVFAYMDDVVLGAKSVEHLESV    AAGTGAATCGAGTTGTTCTGGTTTGGGATGGGCTAGGAGAATGTTGTCCATATAGTGATATATAAGACATGAGGGAAAGGCTCT

现在想:
1,一个bash或者python脚本,提取每一行信息,转换为两行内容,第一行是第一段,且以>开头,第二行是12段。原来两行信息转换以后就变成4行信息。转换到新的文件,文件名.fasta。以上内容就变成:

SRR329659.fasta

>SRR329659.5585.1
VRRNFPHCMVFAYMDDVVLGAKSVEHLES
>SRR329659.40047.1
RNFPHCMVFAYMDDVVLGAKSVEHLESV

2,一个文件夹下有大量类似小文件,需要将这类文件批量转换,文件名.m8,转换成:文件名.fasta。bash或者python脚本输入一个文件夹位置1——里面是待转换文件,输出另外一个文件夹位置2——转换好的文件。
运行命令类似于 bash file-trans.sh 输入文件夹1 输出文件夹2

# -*- utf8 -*-
"""
pyCode : test.py
Created by: Taro
Description:
2022/3/20 0020
"""
import os
import os.path as osp
import sys
if len(sys.argv) != 3:
    print("usage: python trans.py source_dir out_dir")

source_dir = sys.argv[1]
if not osp.exists(source_dir):
    print("input source_dir is not exist,please check!")
out_dir = sys.argv[2]
if not osp.exists(out_dir):
    os.makedirs(out_dir)
count = 0
for root, dirs, files in os.walk(source_dir):
    for f in files:
        if f.endswith(".m8"):
            print("start trans: ", f,)
            count += 1
            infile = osp.join(root, f)
            outfile = f.replace('.m8', ".fasta")
            outfile = osp.join(out_dir, outfile)
            with open(infile, 'r', encoding='utf-8') as inf:
                with open(outfile, 'w', encoding='utf-8') as wf:
                    for i, line in enumerate(inf):
                        # import  pdb
                        # pdb.set_trace()
                        source_line = line.strip().split()
                        line =[]
                        for tmp in source_line:
                            if tmp:
                                line.append(tmp)
                        if len(line) < 12:
                            print("file:{},line:{},format is not right ,please check!")
                            continue
                        else:
                            wf.write(">"+line[0]+"\n"+line[11]+"\n")
            # print("end trans")
print("total trans:", count)

例如拷贝到 test.py 使用方法就是:python test.py inputdir outputdir

trans.sh

#/usr/bin/bash

if [ $# -ne 2 ]; then
    echo "Usage:"
    echo "  sh $0 input-file output-dir"
    exit
fi

input_file=$1
output_dir=$2
fname=`basename -s .m8 "$input_file"`
output_file="$output_dir/$fname.fasta"
echo "Translating \"$input_file\" to \"$output_file\""
cat "$input_file" | awk '{ print "<" $1 "\n" $12 }' > $output_file

run.sh

#!/bin/bash

if [ $# -ne 2 ] ; then
    echo "Usage:"
    echo "  sh $0 input-dir output-dir"
    exit
fi

input_dir=$1
output_dir=$2
find "$input_dir" -type f -name "*.m8" -exec sh ./trans.sh {} "$output_dir" \;
bash run.sh input-dir output-dir
import os,pathlib

#用生成器避免文件过多耗用太多内存,获取文件名
def get_file(path=None,name='.m8'):
    if not path:
        path=pathlib.Path(".")
    for i in os.listdir(path):
        if os.path.isfile(i) and i.endswith(name):
            yield os.path.join(path,i)

#sep默认分割四个空格,如果不对自己修改
def read_file(infilepath,sep="    "):
    with open(infilepath,'r') as r:
        for i in r:
            yield i.split(sep)

def write_file(outfile,data=None):
    with open(outfile,'a') as w:
        w.write(data)

        
#可更换为目标路径
PATH=None
#文件后缀
SUFFIX='.m8'


if __name__=="__main__":       
     
    for i in get_file(PATH,SUFFIX):
        filename=i.replace(SUFFIX,'.fasta')
        for k in read_file(i):
            first,*middle,end1,end2=k
            #此处用四个空格代替Tab如果不合适自己修改
            data=f">{first}\n{end1}    {end2}    "+"    ".join(middle)+'\n'
            write_file(filename,data)

import os
import sys

inpath = r"E:/xxx" #读取目录路径
outpath = r"E:/xxx2" #输出目录路径

FileNames=os.listdir(inpath)
for fn in FileNames:
    if fn.endswith(".m8"):
        print(fn)
        afn=os.path.join(inpath,fn)
        afn2=os.path.join(outpath,fn.replace(".m8",".fasta"))
        with open(afn, 'r', encoding='utf-8') as rf, open(afn2, 'w', encoding='utf-8') as wf:
            for lien in rf.readlines():
                li = lien.split('\t')
                wf.write(f'>{li[0]}\n{li[11]}\n')

如有帮助,请点击我的回答下方的【采纳该答案】按钮帮忙采纳下,谢谢!

img

打开tab readeline 遍历每一行。
每一行处理 用 .split('\t') 拆分,list分成2部分,list[:-1],list[-1]两个部分
最后字符串最后拼接成

"".join(list[:-1])  + "\n" + list[-1]

就是你要的部分了。

然后with open文档按照你的逻辑写就行了。

如果非要在命令行输入参数 用sys

inpath = sys.argv[1]   #读取路径
outpath = sys.argv[2]  #输出路径
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632