web-dev-qa-db-ja.com

zipファイルから抽出したファイルの名前を変更する

Linuxサーバーにたくさんのzipファイルがあり、各ファイルには複数のテキストファイルが含まれています。

私が欲しいのは、zipファイル全体で同じ名前のテキストファイルをいくつか抽出してフォルダーに保存することです。 zipファイルごとに1つのフォルダーを作成し、そこにテキストファイルを抽出します。親のzipフォルダー名をファイル名の最後に追加し、すべてのテキストファイルを1つのディレクトリに保存する必要があります。たとえば、zipフォルダーがMarch132017.Zipで、holding.txtを抽出した場合、ファイル名はholding_march13207.txtになります。

私の問題は、抽出されたファイルの名前を変更できないことです。アドバイスをいただければ幸いです。

import os 
import sys 
import zipfile
os.chdir("/feeds/lipper/emaxx") 

pwkwd = "/feeds/lipper/emaxx" 

for item in os.listdir(pwkwd): # loop through items in dir
    if item.endswith(".Zip"): # check for ".Zip" extension
        file_name = os.path.abspath(item) # get full path of files
        fh = open(file_name, "rb")
        Zip_ref = zipfile.ZipFile(fh)

        filelist = 'ISSUERS.TXT' , 'SECMAST.TXT' , 'FUND.TXT' , 'HOLDING.TXT'
        for name in filelist :
            try:
                outpath = "/SCRATCH/emaxx" + "/" + os.path.splitext(item)[0]
                Zip_ref.extract(name, outpath)

            except KeyError:
                {}

        fh.close()
7
Roo

問題のファイルを読み取って、抽出する代わりに自分で保存してみませんか?何かのようなもの:

import os
import zipfile

source_dir = "/feeds/lipper/emaxx"  # folder with Zip files
target_dir = "/SCRATCH/emaxx"  # folder to save the extracted files

# Are you sure your files names are capitalized in your Zip files?
filelist = ['ISSUERS.TXT', 'SECMAST.TXT', 'FUND.TXT', 'HOLDING.TXT']

for item in os.listdir(source_dir):  # loop through items in dir
    if item.endswith(".Zip"):  # check for ".Zip" extension
        file_path = os.path.join(source_dir, item)  # get Zip file path
        with zipfile.ZipFile(file_path) as zf:  # open the Zip file
            for target_file in filelist:  # loop through the list of files to extract
                if target_file in zf.namelist():  # check if the file exists in the archive
                    # generate the desired output name:
                    target_name = os.path.splitext(target_file)[0] + "_" + os.path.splitext(file_path)[0] + ".txt"
                    target_path = os.path.join(target_dir, target_name)  # output path
                    with open(target_path, "w") as f:  # open the output path for writing
                        f.write(zf.read(target_file))  # save the contents of the file in it
                # next file from the list...
    # next Zip file...
6
zwer
import zipfile

zipdata = zipfile.ZipFile('somefile.Zip')
zipinfos = zipdata.infolist()

# iterate through each file
for zipinfo in zipinfos:
    # This will do the renaming
    zipinfo.filename = do_something_to(zipinfo.filename)
    zipdata.extract(zipinfo)

参照: https://bitdrop.st0w.com/2010/07/23/python-extracting-a-file-from-a-Zip-file-with-a-different-name/

2

各ファイルが正しく抽出された後、名前を変更するだけで済みますか? os.rename トリックを行う必要があります。

Zip_ref.extract(name, outpath)
parent_Zip = os.path.basename(os.path.dirname(outpath)) + ".Zip"
new_file_name = os.path.splitext(os.path.basename(name))[0] # just the filename

new_name_path = os.path.dirname(outpath) + os.sep + new_file_name + "_" + parent_Zip
os.rename(outpath, new_namepath)

ファイル名については、増分にしたい場合は、カウントを開始し、ファイルごとに上に移動します。

count = 0
for file in files:
    count += 1
    # ... Do our file actions
    new_file_name = original_file_name + "_" + str(count)
    # ...

または、終了名を気にしない場合は、いつでもuuidのようなものを使用できます。

import uuid
random_name = uuid.uuid4()
1
mccatnm
outpath = '/SCRATCH/emaxx'
suffix = os.path.splitext(item)[0]

for name in filelist :
    index = Zip_ref.namelist().find(name)
    if index != -1: # check the file exists in the zipfile
        filename, ext = os.path.splitext(name)
        Zip_ref.filelist[index].filename = f'{filename}_{suffix}.{ext}' # rename the extracting file to the suffix file name
        Zip_ref.extract(Zip_ref.filelist[index], outpath) # use the renamed file descriptor to extract the file
0
floydwch

抽出中にファイルの名前を変更できるとは思えません。抽出されたファイルの名前を変更するのはどうですか?

Linux bashに依存しているため、1行でそれを実現できます。

os.system("find "+outpath+" -name '*.txt' -exec echo mv {} `echo {} | sed s/.txt/"+zipName+".txt/` \;")

したがって、最初に指定されたフォルダー内のすべてのtxtファイルを検索し、次にsedによって計算された新しい名前で名前変更コマンドを実行します。

コードはテストされていません、私は今ウィンドウズにいます^^ '

0
technico