Saltar al contenido

¿Cómo puedo comprimir (/ zip) y descomprimir (/ descomprimir) archivos y carpetas con archivos por lotes sin utilizar herramientas externas?

Nuestro grupo de expertos pasados ciertos días de trabajo y de juntar de información, obtuvimos la respuesta, queremos que te sea útil en tu trabajo.

Solución:

Y aquí están las respuestas:

1. Usando un script por lotes “puro” para comprimir / descomprimir el archivo.

Es posible gracias a ZIP.CMD y UNZIP.CMD de Frank Westlake (necesita permisos de administrador y requiere FSUTIL y CERTUTILPara Win2003 y WinXP, necesitará 2003 Admin Tool Pack que se instalará CERTUTIL. Tenga cuidado porque la sintaxis ZIP.CMD está al revés:

ZIP.CMD destination.zip source.file

Y solo puede comprimir archivos individuales.

2. Usando Shell.Application

Pasé algún tiempo para crear un solo script híbrido jscript / batch para uso común que comprime / descomprime archivos y directorios (además de algunas características más).Aquí hay un enlace (se volvió demasiado grande para publicar en la respuesta). Puede usarse directamente con su .bat extensión y no crea ningún archivo temporal. Espero que el mensaje de ayuda sea lo suficientemente descriptivo de cómo se puede utilizar.

Algunos ejemplos:

// unzip content of a zip to given folder.content of the zip will be not preserved (-keep no).Destination will be not overwritten (-force no)
call zipjs.bat unzip -source C:myDirmyZip.zip -destination C:MyDir -keep no -force no

// lists content of a zip file and full paths will be printed (-flat yes)
call zipjs.bat list -source C:myZip.zipinZipDir -flat yes

// lists content of a zip file and the content will be list as a tree (-flat no)
call zipjs.bat list -source C:myZip.zip -flat no

// prints uncompressed size in bytes
zipjs.bat getSize -source C:myZip.zip

// zips content of folder without the folder itself
call zipjs.bat zipDirItems -source C:myDir -destination C:MyZip.zip -keep yes -force no

// zips file or a folder (with the folder itslelf)
call zipjs.bat zipItem -source C:myDirmyFile.txt -destination C:MyZip.zip -keep yes -force no

// unzips only part of the zip with given path inside
call zipjs.bat unZipItem -source C:myDirmyZip.zipInzipDirInzipFile -destination C:OtherDir -keep no -force yes
call zipjs.bat unZipItem -source C:myDirmyZip.zipInzipDir -destination C:OtherDir 

// adds content to a zip file
call zipjs.bat addToZip -source C:some_file -destination C:myDirmyZip.zipInzipDir -keep no
call zipjs.bat addToZip -source  C:some_file -destination C:myDirmyZip.zip

Algunos problemas conocidos durante la compresión:

  • si no hay suficiente espacio en la unidad del sistema (generalmente C :), el script puede producir varios errores, la mayoría de las veces el script se detiene. Shell.Application utiliza activamente %TEMPERATURA% carpeta para comprimir / descomprimir los datos.
  • Las carpetas y archivos que contienen símbolos Unicode en sus nombres no pueden ser manejados por el objeto Shell.Application.
  • El tamaño máximo admitido de los archivos zip producidos es de alrededor de 8 GB en Vista y superior y alrededor de 2 GB en XP / 2003

El script detecta si aparece un mensaje de error y detiene la ejecución e informa de las posibles razones. En este momento no tengo forma de detectar el texto dentro de la ventana emergente y dar la razón exacta del error.

3. Makecab

Comprimir un archivo es fácil: makecab file.txt "file.cab" . Finalmente MaxCabinetSize podría incrementarse. Comprimir una carpeta requiere un uso DestinationDir directiva (con rutas relativas) para cada (sub) directorio y los archivos dentro. Aquí tienes un guión:

;@echo off

;;;;; rem start of the batch part  ;;;;;
;
;for %%a in (/h /help -h -help) do ( 
;   if /I "%~1" equ "%%~a" if "%~2" equ "" (
;       echo compressing directory to cab file  
;       echo Usage:
;       echo(
;       echo %~nx0 "directory" "cabfile"
;       echo(
;       echo to uncompress use:
;       echo EXPAND cabfile -F:* .
;       echo(
;       echo Example:
;       echo(
;       echo %~nx0 "c:directorylogs" "logs"
;       exit /b 0
;   )
; )
;
; if "%~2" EQU "" (
;   echo invalid arguments.For help use:
;   echo %~nx0 /h
;   exit /b 1
;)
;
; set "dir_to_cab=%~f1"
;
; set "path_to_dir=%~pn1"
; set "dir_name=%~n1" 
; set "drive_of_dir=%~d1"
; set "cab_file=%~2"
;
; if not exist %dir_to_cab% (
;   echo no valid directory passed
;   exit /b 1
;)

;
;break>"%tmp%makecab.dir.ddf"
;
;setlocal enableDelayedExpansion
;for /d /r "%dir_to_cab%" %%a in (*) do (
;   
;   set "_dir=%%~pna"
;   set "destdir=%dir_name%!_dir:%path_to_dir%=!"
;   (echo(.Set DestinationDir=!destdir!>>"%tmp%makecab.dir.ddf")
;   for %%# in ("%%a*") do (
;       (echo("%%~f#"  /inf=no>>"%tmp%makecab.dir.ddf")
;   )
;)
;(echo(.Set DestinationDir=!dir_name!>>"%tmp%makecab.dir.ddf")
;   for %%# in ("%~f1*") do (
;       
;       (echo("%%~f#"  /inf=no>>"%tmp%makecab.dir.ddf")
;   )

;makecab /F "%~f0" /f "%tmp%makecab.dir.ddf" /d DiskDirectory1=%cd% /d CabinetNameTemplate=%cab_file%.cab
;rem del /q /f "%tmp%makecab.dir.ddf"
;exit /b %errorlevel%

;;
;;;; rem end of the batch part ;;;;;

;;;; directives part ;;;;;
;;
.New Cabinet
.set GenerateInf=OFF
.Set Cabinet=ON
.Set Compress=ON
.Set UniqueFiles=ON
.Set MaxDiskSize=1215751680;

.set RptFileName=nul
.set InfFileName=nul

.set MaxErrors=1
;;
;;;; end of directives part ;;;;;

Uso de ejemplo:

call cabDir.bat ./myDir compressedDir.cab

Para descompresión EXPAND cabfile -F:* . Para la extracción en Unix se puede usar cabextract o 7zip.

4. .NET y GZipStream

Preferí un Jscript.net ya que permite una hibridación ordenada con .bat (sin salida tóxica y sin archivos temporales) .Jscript no permite pasar una referencia de objeto a una función, por lo que la única forma que encontré para hacerlo funcionar es mediante leer / escribir archivos byte a byte (así que supongo que no es la forma más rápida, ¿cómo se puede hacer la lectura / escritura en búfer?). Nuevamente, solo se puede usar con archivos individuales.

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%Microsoft.NETFramework*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

 %~n0.exe %*

endlocal & exit /b %errorlevel%


*/


import System;
import System.Collections.Generic;
import System.IO;
import System.IO.Compression;


    
    function CompressFile(source,destination)
        var sourceFile=File.OpenRead(source);
        var destinationFile=File.Create(destination);
        var output = new  GZipStream(destinationFile,CompressionMode.Compress);
        Console.WriteLine("Compressing 0 to 1.", sourceFile.Name,destinationFile.Name, false);
        var byteR = sourceFile.ReadByte();
        while(byteR !=- 1)
            output.WriteByte(byteR);
            byteR = sourceFile.ReadByte();
        
        sourceFile.Close();
        output.Flush();
        output.Close();
        destinationFile.Close();
    

    function UncompressFile(source,destination)
        var sourceFile=File.OpenRead(source);
        var destinationFile=File.Create(destination);
        
        var input = new GZipStream(sourceFile,
            CompressionMode.Decompress, false);
        Console.WriteLine("Decompressing 0 to 1.", sourceFile.Name,
                destinationFile.Name);
        
        var byteR=input.ReadByte();
        while(byteR !== -1)
            destinationFile.WriteByte(byteR);
            byteR=input.ReadByte();
        
        destinationFile.Close();
        input.Close();
        
        
    
    
var arguments:String[] = Environment.GetCommandLineArgs();

    function printHelp()
        Console.WriteLine("Compress and uncompress gzip files:");
        Console.WriteLine("Compress:");
        Console.WriteLine(arguments[0]+" -c source destination");
        Console.WriteLine("Uncompress:");
        Console.WriteLine(arguments[0]+" -u source destination");
        
        
    

if (arguments.length!=4)
    Console.WriteLine("Wrong arguments");
    printHelp();
    Environment.Exit(1);


switch (arguments[1])
    case "-c":
    
        CompressFile(arguments[2],arguments[3]);
        break;
    case "-u":
        UncompressFile(arguments[2],arguments[3]);
        break;
    default:
        Console.WriteLine("Wrong arguments");
        printHelp();
        Environment.Exit(1);

Uso de ejemplo:

//zip
call netzip.bat -c my.file my.zip
//unzip
call netzip.bat -u my.zip my.file

5. TAR (solo para las versiones más recientes de Windows)

Con las últimas versiones de Windows 10, ahora tenemos el comando TAR, aunque no es la opción más compatible con versiones anteriores:

//compress directory
tar -cvf archive.tar c:my_dir
//extract to dir
tar -xvf archive.tar.gz -C c:data

soluciones asombrosas!

La solución makecab tiene algunos problemas, por lo que aquí hay una versión fija que resuelve el problema al usar directorios con espacios en blanco.

;@echo off

;;;;; rem start of the batch part  ;;;;;
;
;for %%a in (/h /help -h -help) do ( 
;   if /I "%~1" equ "%%~a" if "%~2" equ "" (
;       echo compressing directory to cab file  
;       echo Usage:
;       echo(
;       echo %~nx0 "directory" "cabfile"
;       echo(
;       echo to uncompress use:
;       echo EXPAND cabfile -F:* .
;       echo(
;       echo Example:
;       echo(
;       echo %~nx0 "c:directorylogs" "logs"
;       exit /b 0
;   )
; )
;
; if "%~2" EQU "" (
;   echo invalid arguments.For help use:
;   echo %~nx0 /h
;   exit /b 1
;)
;
; set "dir_to_cab=%~f1"
;
; set "path_to_dir=%~pn1"
; set "dir_name=%~n1" 
; set "drive_of_dir=%~d1"
; set "cab_file=%~2"
; 
; if not exist "%dir_to_cab%" (
;   echo no valid directory passed
;   exit /b 1
;)

;
;break>"%tmp%makecab.dir.ddf"
;
;setlocal enableDelayedExpansion
;for /d /r "%dir_to_cab%" %%a in (*) do (
;   
;   set "_dir=%%~pna"
;   set "destdir=%dir_name%!_dir:%path_to_dir%=!"
;   (echo(.Set DestinationDir=!destdir!>>"%tmp%makecab.dir.ddf")
;   for %%# in ("%%a*") do (
;       (echo("%%~f#"  /inf=no>>"%tmp%makecab.dir.ddf")
;   )
;)
;(echo(.Set DestinationDir=!dir_name!>>"%tmp%makecab.dir.ddf")
;   for %%# in ("%~f1*") do (
;       
;       (echo("%%~f#"  /inf=no>>"%tmp%makecab.dir.ddf")
;   )

;makecab /F "%~f0" /f "%tmp%makecab.dir.ddf" /d DiskDirectory1="%cd%" /d CabinetNameTemplate=%cab_file%.cab
;rem del /q /f "%tmp%makecab.dir.ddf"
;exit /b %errorlevel%

;;
;;;; rem end of the batch part ;;;;;

;;;; directives part ;;;;;
;;
.New Cabinet
.set GenerateInf=OFF
.Set Cabinet=ON
.Set Compress=ON
.Set UniqueFiles=ON
.Set MaxDiskSize=1215751680;

.set RptFileName=nul
.set InfFileName=nul

.set MaxErrors=1
;;
;;;; end of directives part ;;;;;

CAB.bat [input] carpeta o archivo: paquete | .cab o. ?? _: desempaquetar | ninguno: paquete a files subcarpeta
También agregará un CAB entrada para hacer clic con el botón derecho en el menú Enviar a para facilitar el manejo
Dado que este hace ambas tareas a la perfección, debería preferirse al feo makecab, ¿por qué usar un script híbrido si escribe en un archivo temporal de todos modos?

@echo off &echo. &set "ext=%~x1" &title CAB [%1] &rem input file or folder / 'files' folder / unpacks .cab .??_
if "_%1"=="_" if not exist "%~dp0files" echo CAB: No input and no 'files' directory to pack &goto :Exit "do nothing"
if "_%1"=="_" if exist "%~dp0files" call :CabDir "%~dp0files" &goto :Exit "input = none, use 'files' directory -pack" 
for /f "tokens=1 delims=r-" %%I in ("%~a1") do if "_%%I"=="_d" call :CabDir "%~f1" &goto :Exit "input = dir -pack"
if not "_%~x1"=="_.cab" if not "_%ext:~-1%"=="__" call :CabFile "%~f1" &goto :Exit "input = file -pack"
call :CabExtract "%~f1" &goto :Exit "input = .cab or .??_ -unpack" 
:Exit AveYo: script will add a CAB entry to right-click -- SendTo menu
if not exist "%APPDATA%MicrosoftWindowsSendToCAB.bat" copy /y "%~f0" "%APPDATA%MicrosoftWindowsSendToCAB.bat" >nul 2>nul
ping -n 6 localhost >nul &title cmd.exe &exit /b
:CabExtract %1:[.cab or .xx_]
echo %1 &pushd "%~dp1" &mkdir "%~n1" >nul 2>nul &expand -R "%~1" -F:* "%~n1" &popd &goto :eof
:CabFile %1:[filename]
echo %1 &pushd "%~dp1" &makecab /D CompressionType=LZX /D CompressionLevel=7 /D CompressionMemory=21 "%~nx1" "%~n1.cab" &goto :eof   
:CabDir %1:[directory]
dir /a:-D/b/s "%~1"
set "ddf="%temp%ddf""
echo/.New Cabinet>%ddf%
echo/.set Cabinet=ON>>%ddf%
echo/.set CabinetFileCountThreshold=0;>>%ddf%
echo/.set Compress=ON>>%ddf%
echo/.set CompressionType=LZX>>%ddf%
echo/.set CompressionLevel=7;>>%ddf%
echo/.set CompressionMemory=21;>>%ddf%
echo/.set FolderFileCountThreshold=0;>>%ddf%
echo/.set FolderSizeThreshold=0;>>%ddf%
echo/.set GenerateInf=OFF>>%ddf%
echo/.set InfFileName=nul>>%ddf%
echo/.set MaxCabinetSize=0;>>%ddf%
echo/.set MaxDiskFileCount=0;>>%ddf%
echo/.set MaxDiskSize=0;>>%ddf%
echo/.set MaxErrors=1;>>%ddf%
echo/.set RptFileName=nul>>%ddf%
echo/.set UniqueFiles=ON>>%ddf%
setlocal enabledelayedexpansion
pushd "%~dp1"
for /f "tokens=* delims=" %%D in ('dir /a:-D/b/s "%~1"') do (
 set "DestinationDir=%%~dpD" &set "DestinationDir=!DestinationDir:%~1=!" &set "DestinationDir=!DestinationDir:~0,-1!"
 echo/.Set DestinationDir=!DestinationDir!;>>%ddf%
 echo/"%%~fD"  /inf=no;>>%ddf%
)
makecab /F %ddf% /D DiskDirectory1="" /D CabinetNameTemplate=%~nx1.cab &endlocal &popd &del /q /f %ddf% &goto :eof

Si te ha resultado de ayuda nuestro artículo, nos gustaría que lo compartas con el resto seniors de este modo contrubuyes a difundir nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *