2017-04-17 200 views
0

我編寫了一個python腳本,它從列表中讀取文件偏移量和文件名,並將一個大文件劃分爲多個文件。爲了分裂,我使用了shell腳本,它將這些名稱和偏移量作爲輸入,並使用head命令創建多個輸出文件。我正在使用python將輸入發送到shell腳本。這在我的Windows 7和其他Linux系統中工作正常。但是,當我嘗試在ESX 6.5管理程序上使用相同的功能時,我意識到我無法在ESX 6.5中使用相同的shell腳本,因爲head命令不工作,因爲它在其他操作系統中工作。如何使用Python將單個文件分割成多個不同大小的文件

列表= [ '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中,只有第一個head命令輸出正在工作。

是否有另一種分割文件的方法。我知道有分割命令,但這個命令將文件分成兩半。我需要動態大小文件。 我希望如果我可以從python本身進行拆分。順便說一句,我是Python的新手。

+1

是否希望按行或塊大小拆分文件?文件文本還是二進制文件?或劑量它重要? –

+0

我想分塊大小的文件。文件包含文本和二進制數據。 –

+0

我推薦這個鏈接:https://www.safaribooksonline.com/library/view/programming-python-second/0596000855/ch04s02.html和這個鏈接在stackoverflow:http://stackoverflow.com/questions/8096614/split -large-files-using-python –

回答

0

從您嘗試的解決方案中可以看出,您是Python的新手,但實際上使用subprocess庫取得了令人驚訝的進步,所以我相信您會發現,時光流逝。通常一個問題似乎很難,因爲你根本不知道可用工具的所有可用功能。在這種情況下,您似乎在使用head,因爲您知道可以強制執行您想要的任務,但我相信您會同意這不是一個舒適的解決方案。

很難處理任何需要19個參數的程序 - 這些命令變得相當難以理解,並且在編寫它們時出錯很容易。一種數據驅動的方法,您在文本文件中描述瞭如何分割文件,可能更容易理解。然後,您可以編寫一個讀取該描述並使用它來分割文件的程序。由於Python可以很容易地讀取和寫入文件,因此您應該發現根本不需要使用shell腳本,這將使您的解決方案更具可移植性。

如果我理解正確的話你的shell腳本,每個head命令從十九(!)參數命名的文件中的特定字節數,並寫出它們到一個指定的文件。所以,你可以使用包含表單

N filename 

其中N是行數,以BEO讓我在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 

希望你將能夠適應這個非常輕鬆地解決你的問題。

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獲得所有剩餘的數據。

相關問題