简体   繁体   English

如何在不解压缩和重新压缩的情况下重命名 zip 存档中的文件?

[英]How to rename files in zip archive without extracting and recompressing them?

I need to rename all the files on a zip file from AAAAA-filename.txt to BBBBB-filename.txt , and I want to know if I can automate this task without having to extract all files, rename and then zip again.我需要将 zip 文件中的所有文件从AAAAA-filename.txt重命名为BBBBB-filename.txt ,我想知道是否可以自动执行此任务而无需提取所有文件、重命名然后再次压缩。 Unzipping one at a time, renaming and zipping again is acceptable.一次解压缩一个,重命名并再次压缩是可以接受的。

What I have now is:我现在拥有的是:

for file in *.zip
do
    unzip $file
    rename_txt_files.sh
    zip *.txt $file
done;

But I don't know if there is a fancier version of this where I don't have to use all that extra disk space.但我不知道是否有更高级的版本,我不必使用所有额外的磁盘空间。

plan计划

  • find offsets of filenames with strings用字符串查找文件名的偏移量
  • use dd to overwrite new names ( note will only work with same filename lengths ).使用 dd 覆盖新名称(注意仅适用于相同的文件名长度)。 otherwise would also have to find and overwrite the filenamelength field..否则还必须找到并覆盖文件名长度字段..

backup your zipfile before trying this在尝试之前备份您的 zipfile

zip_rename.sh zip_rename.sh

#!/bin/bash

strings -t d test.zip | \
grep '^\s\+[[:digit:]]\+\sAAAAA-\w\+\.txt' | \
sed 's/^\s\+\([[:digit:]]\+\)\s\(AAAAA\)\(-\w\+\.txt\).*$/\1 \2\3 BBBBB\3/g' | \
while read -a line; do
  line_nbr=${line[0]};
  fname=${line[1]};
  new_name=${line[2]};
  len=${#fname};
#  printf "line: "$line_nbr"\nfile: "$fname"\nnew_name: "$new_name"\nlen: "$len"\n";
  dd if=<(printf $new_name"\n") of=test.zip bs=1 seek=$line_nbr count=$len conv=notrunc  
done;

output输出

$ ls
AAAAA-apple.txt  AAAAA-orange.txt  zip_rename.sh
$ zip test.zip AAAAA-apple.txt AAAAA-orange.txt 
  adding: AAAAA-apple.txt (stored 0%)
  adding: AAAAA-orange.txt (stored 0%)
$ ls
AAAAA-apple.txt  AAAAA-orange.txt  test.zip  zip_rename.sh
$ ./zip_rename.sh 
15+0 records in
15+0 records out
15 bytes (15 B) copied, 0.000107971 s, 139 kB/s
16+0 records in
16+0 records out
16 bytes (16 B) copied, 0.000109581 s, 146 kB/s
15+0 records in
15+0 records out
15 bytes (15 B) copied, 0.000150529 s, 99.6 kB/s
16+0 records in
16+0 records out
16 bytes (16 B) copied, 0.000101685 s, 157 kB/s
$ unzip test.zip 
Archive:  test.zip
 extracting: BBBBB-apple.txt         
 extracting: BBBBB-orange.txt        
$ ls
AAAAA-apple.txt   BBBBB-apple.txt   test.zip
AAAAA-orange.txt  BBBBB-orange.txt  zip_rename.sh
$ diff -qs AAAAA-apple.txt BBBBB-apple.txt 
Files AAAAA-apple.txt and BBBBB-apple.txt are identical
$ diff -qs AAAAA-orange.txt BBBBB-orange.txt 
Files AAAAA-orange.txt and BBBBB-orange.txt are identical

We used python to我们使用 python 来

  1. Extract xyz.zip file to xyz_renamed/ folderxyz.zip文件解压到xyz_renamed/文件夹
  2. Rename the desired files (we are only renaming jpeg and png images) in renameFile function (we are changing names to lower)renameFile函数中重命名所需的文件(我们只重命名 jpeg 和 png 图像)(我们将名称更改为更低)
  3. Package the renamed contents again in xyz_renamed.zip将重命名的内容再次打包到xyz_renamed.zip
  4. Delete the xyz_renamed/ folder and xyz.zip file删除xyz_renamed/文件夹和xyz.zip文件
  5. Renaming xyz_renamed.zip to xyz.zipxyz_renamed.zip重命名为xyz.zip
import os
from zipfile import ZipFile
import shutil

# rename the individual file and return the absolute path of the renamed file
def renameFile(root, fileName):
    toks = fileName.split('.')
    newName = toks[0].lower()+'.'+toks[1]
    renamedPath =  os.path.join(root,newName)
    os.rename(os.path.join(root,fileName),renamedPath)
    return renamedPath

def renameFilesInZip(filename):
    # Create <filename_without_extension>_renamed folder to extract contents into
    head, tail = os.path.split(filename)
    newFolder = tail.split('.')[0]
    newFolder += '_renamed'
    newpath = os.path.join(head, newFolder)
    if(not os.path.exists(newpath)):
        os.mkdir(newpath)

    # extracting contents into newly created folder
    print("Extracting files\n")
    try:
        with ZipFile(filename, 'r', allowZip64=True) as zip_ref:
            zip_ref.extractall(newpath)
        zip_ref.close()
    except ResponseError as err:
        print(err)
        return -1

    # track the files that need to be repackaged in the zip with renamed files
    filesToPackage = []

    for r, d, f in os.walk(newpath):
        for item in f:
            # filter the file types that need to be renamed
            if item.lower().endswith(('.jpg', '.png')):
                # renaming file
                renamedPath = renameFile(r, item)
                filesToPackage.append(renamedPath)
            else:
                filesToPackage.append(os.path.join(r,item))


    # creating new zip file
    print("Writing renamed file\n")

    zipObj = ZipFile(os.path.join(head, newFolder)+'.zip', 'w', allowZip64 = True)
    for file in filesToPackage:
        zipObj.write(file, os.path.relpath(file, newpath))
    zipObj.close()

    # removing extracted contents and origianl zip file
    print('Cleaning up \n')
    shutil.rmtree(newpath)
    os.remove(filename)

    # renaming zipfile with renamed contents to original zipfile name
    os.rename(os.path.join(head, newFolder)+'.zip', filename)

Use the following code to invoke the renaming function for multiple zip files使用以下代码调用多个zip文件的重命名功能


if __name__ == '__main__':

    # zipfiles with contents to be renamed
    zipFiles = ['/usr/app/data/mydata.zip', '/usr/app/data/mydata2.zip']
    
    # do the renaming for all files one by one
    for _zip in zipFiles:
        renameFilesInZip(_zip)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不解压缩的情况下列出 zip 存档中的文件? - How can I list the files in a zip archive without decompressing it? 如何在没有中间文件夹的情况下将文件添加到zip存档 - How to add files to zip archive without a intermediate folder 使用7zip解压缩文件后,如何重命名这些文件并保存 - After extracting files with 7zip how can you rename those file and save Linux - 如何在不提取内容并再次应用 tar 的情况下重命名 .tgz 文件中的文件? - Linux - how to rename files within a .tgz file without extracting contents and applying tar again? 如何在不提取的情况下获取 zip 中所有文件的 md5sum - How can i get md5sum for all files inside zip without extracting 如何在 linux 上使用 zip 生成新存档,而不仅仅是刷新存档中的文件并将文件添加到其中? - How to use zip to generate a new archive but not just refresh files in the archive and add files into it, on linux? 如何使用 linux 'tar' 重命名放入 tar 存档的文件 - how to rename files you put into a tar archive using linux 'tar' 我如何搜索文件并将其压缩在一个zip文件中 - how can i search for files and zip them in one zip file 在tar归档文件中移动和重命名文件 - Move and rename files within a tar archive 在linux机器上创建一个自解压zip存档 - Creating a self-extracting zip archive on a linux box
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM