如何使用Python将单个文件拆分为多个不同大小的文件

2024-09-30 18:21:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个python脚本,从列表中读取文件偏移量和文件名,并将一个大文件分成多个文件。对于拆分,我使用shell脚本,它将这些名称和偏移量作为输入,并使用head命令创建多个输出文件。我使用python将输入发送到shell脚本。这在我的Windows7和其他Linux系统中运行良好。但是,当我试图在esx6.5hypervisor上使用相同的脚本时,我意识到我不能在esx6.5中使用相同的shell脚本,因为head command不能像在其他操作系统中那样工作。在

list=['IdleChk_1_E1.txt','749','IdleChk_2_E1.txt','749','reg_fifo_E1.txt','5922','igu_fifo_E1.txt','161','protection_override_E1.txt','1904','fw_asserts_E1.txt','708','McpTrace.txt文件'15578','物理_转储.txt','129','GrcDumpE1.bin','3629656']

偶数元素是文件名,奇数元素是大小。在

下面是我用来向shell脚本发送输入的命令:

Process_three=subprocess.Popen("./read.sh %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s" \
                             %(''.join(map(str, list_info[1:2])), ''.join(map(str, list_info[0:1])),\
                               ''.join(map(str, list_info[3:4])), ''.join(map(str, list_info[2:3])),\
                               ''.join(map(str, list_info[5:6])), ''.join(map(str, list_info[4:5])),\
                               ''.join(map(str, list_info[7:8])), ''.join(map(str, list_info[6:7])),\
                               ''.join(map(str, list_info[9:10])), ''.join(map(str, list_info[8:9])),\
                               ''.join(map(str, list_info[11:12])), ''.join(map(str, list_info[10:11])),\
                               ''.join(map(str, list_info[13:14])), ''.join(map(str, list_info[12:13])),\
                               ''.join(map(str, list_info[15:16])), ''.join(map(str, list_info[14:15])),\
                               ''.join(map(str, list_info[17:18])), ''.join(map(str, list_info[16:17])),\
                               file_name), stdout=subprocess.PIPE, shell=True)
(temp, error) = Process_three.communicate()

这是我的shell脚本。在

^{pr2}$

在ESX中,只有第一个头命令输出有效。在

有没有其他方法分割文件。我知道有split命令,但是这个命令将文件分成两半。我需要动态大小的文件。 我希望我能从python中分离出来。顺便说一下,我是Python新手。在


Tags: 文件命令infotxt脚本map文件名shell
2条回答

首先,我建议将列表转换为2元组的列表,并对数字使用整数而不是字符串。用这种方法更容易。我使用列表而不是dict,因为列表有顺序,而字典没有

fragments = [('IdleChk_1_E1.txt', 749), 
             ('IdleChk_2_E1.txt', 749),
             ('reg_fifo_E1.txt', 5922),
             ('igu_fifo_E1.txt', 161),
             ('protection_override_E1.txt', 1904),
             ('fw_asserts_E1.txt', 708),
             ('McpTrace.txt', 15578),
             ('phy_dump.txt', 129),
             ('GrcDumpE1.bin', 3629656)]

然后我们以二进制模式打开文件(这里我使用的是python3),读取所需数量的数据并将其写入输出文件。在

^{pr2}$

最好检查所有片段大小的总和不大于文件大小。或者您可以使用-1作为最后一个片段的大小,这将使read获得所有剩余的数据。在

从您尝试的解决方案中可以很明显地看出,您是Python的新手,但实际上在使用subprocess库方面取得了相当惊人的进展,因此我相信您会发现随着时间的推移,您会做得更好。通常一个问题似乎很难解决,因为您根本不知道可用工具的所有可用功能。在本例中,您似乎使用了head,因为您知道可以强迫您做您想做的事情,但我相信您会同意这不是一个舒适的解决方案。在

处理任何需要19个参数的过程都很困难——命令变得相当难以理解,而且在编写它们时出错也更容易。数据驱动的方法,即在文本文件中描述如何分割文件,可能更容易处理。然后您可以编写一个程序,读取该描述并利用它来分割文件。由于Python可以非常容易地读写文件,因此您应该发现根本不需要使用shell脚本,这将使您的解决方案更易于移植。在

如果我正确理解了您的shell脚本,那么每个head命令从第十九个(!)中命名的文件中获取一定数量的字节参数并将其写入指定的文件。所以您可以使用包含表单行的数据文件布局

N filename

其中N是要进行测试的行数,我在task_description.txt中创建了以下文件。在

^{pr2}$

就像你的程序一样(如果我没弄错的话),指定的60字节之后的任何字节都将被忽略。所以现在我可以编写一个程序so15.py,它读取任务描述并处理一些数据文件,这些文件在第一个命令行参数中命名,因此:

import sys
in_file = sys.argv[1]
with open("task_description.txt") as td, open(in_file, "rb") as inf:
    for line in td:
        n, file_name = line.split()
        with open(file_name, "wb") as out_file:
            out_file.write(inf.read(int(n)))
        print("Wrote", n, "bytes to", file_name)

然后我使用一个包含超过60个字节的数据文件运行这个文件,这个文件来自Python发行版的Misc/NEWS文件,使用以下命令

python so15.py /Users/sholden/Projects/Python/cpython/Misc/NEWS

它给出了输出

Wrote 10 bytes to file1.txt
Wrote 20 bytes to file2.txt
Wrote 30 bytes to file3.txt

作为检查,我运行了命令

wc -l file*.txt

结果如下

   0       1      10 file1.txt
   2       4      20 file2.txt
   2       6      30 file3.txt
   4      11      60 total

希望你能适应这一点,以解决你的问题相当容易。在

相关问题 更多 >