我编写了一个python脚本,它从列表中读取文件偏移量和文件名,并将一个大文件分成多个文件。对于拆分,我使用shell脚本,它将这些名称和偏移量作为输入,并使用head命令创建多个输出文件。我正在使用python将输入发送到shell脚本。这在我的Windows 7和其他Linux系统中运行良好。但是,当我尝试在ESX 6.5虚拟机管理程序上使用相同的内容时,我意识到我无法在ESX 6.5中使用相同的shell脚本,因为head命令无法正常工作,因为它在其他操作系统中工作。
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','phy_dump.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脚本。
if [ "$#" -eq 19 ];
then
{
head -c $1 > $2
head -c $3 > $4
head -c $5 > $6
head -c $7 > $8
head -c $9 > ${10}
head -c ${11} > ${12}
head -c ${13} > ${14}
head -c ${15} > ${16}
head -c ${17} > ${18}
} < ${19}
fi
在ESX中,只有第一个头命令输出正在运行。
是否有另一种分割文件的方法。我知道有split命令但是这个命令将文件分成两个相等的一半。我需要动态大小的文件。 我希望我能从python本身分裂。顺便说一下,我是Python的新手。
答案 0 :(得分:0)
从您尝试的解决方案中可以明显看出您是Python新手,但实际上您在使用subprocess
库方面取得了相当惊人的进展,所以我相信您会发现自己会随着时间的推移做得更好。通常问题看起来很困难,因为您根本不了解可用工具的所有可用功能。在这种情况下,您似乎正在使用head
,因为您知道可以强制执行您想要的操作,但我相信您会同意这不是一个舒适的解决方案。
处理任何需要19个参数的过程很困难 - 命令变得难以理解,并且在编写错误时更容易出错。数据驱动的方法,您在文本文件中描述您希望如何拆分文件,可能更容易处理。然后,您可以编写一个程序来读取该描述并使用它来分割文件。由于Python可以非常容易地读写文件,因此您应该发现根本不需要使用shell脚本,这将使您的解决方案更加便携。
如果我已正确理解您的shell脚本,则每个head
命令从第19个(!)参数中指定的文件中获取一定数量的字节,并将它们写入指定的文件。因此,您可以使用包含表单行
N filename
其中N是允许我测试的行数我在task_description.txt
创建了以下文件。
10 file1.txt
20 file2.txt
30 file3.txt
就像你的程序一样(如果我说得对),在指定的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
希望你能够很容易地适应这个问题来解决你的问题。
答案 1 :(得分:0)
首先,我建议将列表转换为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)]
然后我们以二进制模式打开文件(我在这里使用Python 3),读取所需的数据量并将其写入输出文件。
with open('inputfile', 'rb') as inf:
for fn, count in fragments:
with open(fn, 'wb') as outf:
outf.write(inf.read(count))
检查所有片段大小的总和不大于文件大小是个好主意。或者您可以使用-1
作为最后一个片段的大小,这将使read
获取所有剩余数据。