¿Herramienta para corregir nombres de archivos que comienzan con =_iso-8859-1... en nombres de archivos .eml?

¿Herramienta para corregir nombres de archivos que comienzan con =_iso-8859-1... en nombres de archivos .eml?

Tengo una carpeta llena de correos electrónicos guardados de una cuenta IMAP que disolví.

El nombre del archivo es la línea de asunto de cada correo electrónico.

Desafortunadamente, cuando se utiliza una codificación que no es ASCII, la línea de asunto se verá como si fuera interna: tendrá el prefijo =_y la codificación utilizada:

=_UTF-8_Q_Auftragsbest=C3=A4tigung_(Kundennummer__)_=_20100819_150312_37.eml

=_windows-1252_Q_Best=E4tigung=3A_Wir_haben_Ihre_=_20100819_150310_28.eml 

¿Alguien conoce alguna herramienta que pueda usarse para solucionar este problema en masa a nivel del sistema de archivos?

Una solución tendría que 1. eliminar el =_ENCODINGprefijo y 2. si es posible, convertir los caracteres codificados en el nombre del archivo a sus diéresis equivalentes en el sistema de archivos adecuado.

Estoy en Windows 7 o XP, pero estaría listo para llevar esto a una máquina virtual Linux porque es unagrandecarpeta y una solución automatizada seríaexcelente.

Respuesta1

Me construí un script PHP. Pensé en compartirlo en caso de que alguien más termine con un problema similar. Funciona para mí y para las codificaciones que necesitaba (es posible que tengas que ampliar la matriz de codificaciones).

El script convierte el archivo codificado MIMEnombresrecursivamente a lo largo de la estructura de directorios especificada en UTF-8.

No produce resultados del todo perfectos: hay varios caracteres especiales que se convierten doblemente o no se convierten en absoluto. Hasta donde puedo ver, esto es culpa del exportador IMAP o de información de codificación incorrecta dentro del propio correo electrónico.

mb_decode_mimeheader()es el corazón de todo el asunto.

Liberado al dominio público; sin garantía alguna. Se requiere PHP 5.2.

Debería ejecutarse tanto en CLI como a través de la web; Lo probé en el navegador.

Haga copias de seguridad antes de ejecutar scripts como este en sus datos.

<?php

 /* Directory to parse */
 $dir = "D:/IMAP";
 /* Extensions to parse. Leave empty for none */
 $extensions = array("eml");
 /* Set to true to actually run the renaming */
 define ("GO", true);

 /* No need to change past this point */  

 /* Output content type header if not in CLI */
 if (strtolower(php_sapi_name()) != "CLI")
  header("Content-type: text/plain; charset=utf-8");


 $FixNames = new FixEmlNames($dir, $extensions);
 $FixNames->fixAll();



  class FixEmlNames
   {

     /* List of possible encodings here */
     private $encodings = array("iso-8859-1", "iso-8859-15", "windows-1252", "utf-8");
     /* Encoding Prefix. The exporter exports e.g. =_iso-8859-1_ with underscores 
        instead of question marks */
     private $encoding_prefix = "=_";
     /* Encoding postfix */
     private $encoding_postfix = "_";
     /* Temporary storage for files */
     private $files;
     /* Array of file extensions to process. Leave empty to parse all files and directories */
     private $extensions = array(); 
     /* Count of renamed files */
     private $count = 0;
     /* Count of failed renames */
     private $failed = 0;
     /* Count of skipped renames */
     private $skipped = 0;
     /* Transform forbidden characters in host OS */
     private $transform_characters = array(":" => "_", "?" => "_", ">" => "_");

     function __construct($dir, $extensions = array("eml"))
       { 

        $this->files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
        $this->extensions = $extensions;
       }

     function fixAll()
      {
        echo "Starting....\n";

        while($this->files->valid())
        {
         if (!$this->files->isDot())
          {

           $path = $this->files->key();
           $ext  = pathinfo($path, PATHINFO_EXTENSION);

           if ((count($this->extensions) == 0 ) or (in_array($ext, $this->extensions)))
            $this->renameOne($path);

          }
         $this->files->next();
        }

        echo "Done. ";

        /* Show stats */
        $status = array();

        if ($this->count > 0) $status[] = $this->count." OK";
        if ($this->failed > 0) $status[] = $this->failed." failed";
        if ($this->skipped > 0) $status[] = $this->skipped." skipped";

        echo implode(", ", $status);


      }

      function  renameOne($fullPath)
       {


          $filename = pathinfo($fullPath, PATHINFO_BASENAME); 
          $is_mime = false;

          // See whether file name is MIME encoded or not
          foreach ($this->encodings as $encoding)
           { if (stristr($filename, $this->encoding_prefix.$encoding.$this->encoding_postfix))
              $is_mime = true;
           }

           // No MIME encoding? Skip.
           if (!$is_mime)
            {
              # uncomment to see skipped files
              # echo "Skipped: $filename\n";
              $this->skipped++;
              return true;
            }

           mb_internal_encoding("UTF-8"); 
           $filename = str_replace("_", "?", $filename);  // Question marks were converted to underscores
           $filename = mb_decode_mimeheader($filename);
           $filename = str_replace("?", "_", $filename);  


           // Remove forbidden characters
           $filename = strtr($filename, $this->transform_characters);

          // Rename
          if (constant("GO") == true)
           {
            // We catch the error manually
            $old = error_reporting(0);
            $success = rename($fullPath, realpath(dirname($fullPath)).DIRECTORY_SEPARATOR.$filename); 
            error_reporting($old);        

          if ($success)
           {
           echo "OK: $filename\n";
           $this->count++; 
           return true;
           }
          else
           {
             $error = error_get_last();
             $message = $error["message"];
             $this->failed++;
             echo "Failed renaming $fullPath. Error message: ".$message."\n";
             return false;
           }
           }
           else
           {
             $this->count++;  
             echo "Simulation: $filename\n";
             return true;   
           }
       }


   }

Respuesta2

Como está dispuesto a pasarse a Linux, puede instalar un servidor php y crear un script bastante sencillo para volver a codificar los archivos. El grado de dificultad depende de si alguna vez has realizado alguna programación. Puede hacer referencia a estas funciones enphp.net

Estas son las funciones que necesitarías

<?php

opendir  ( string $path  [, resource $context  ] )
readdir  ([ resource $dir_handle  ] )
file_get_contents(ENTER THE FILE NAMES HERE WITH A VARIABLE PASSED FROM readdir)
preg_replace(REGULAR EXPRESSION TO REMOVE THE =ENCODING part of the filename)
string mb_convert_encoding  ( string $str  , string $to_encoding  [, mixed $from_encoding  ] )
file_put_contents(THE NEW FILE NAME.eml)

?>

información relacionada