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


2

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

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

Ahora, desafortunadamente, cuando se utiliza una codificación que no es ASCII, la línea de asunto se verá como si se viera internamente, con 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 sabe una herramienta que podría usarse para solucionar esto en el nivel del sistema de archivos?

Una solución tendría que 1. quitar el =_ENCODING prefijo y 2. si es posible, convierta los caracteres codificados en el nombre del archivo a las Umlauts equivalentes a su sistema de archivos adecuado.

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


¿Desea eliminar la referencia a la codificación utilizada en el nombre de archivo? No estoy seguro de cuál es el objetivo final. Quizás use Bulk Rename ( bulkrenameutility.co.uk/Main_Intro.php ) como se menciona en Archivos de cambio de nombre en masa @Pekka
Sathyajith Bhat

Básicamente, necesitas algo como "convmv" con soporte para comillas imprimibles.

Respuestas:


1

Me construí un script PHP. Pensé que lo compartiría en caso de que alguien más tenga un problema similar. Funciona para mí y para las codificaciones que necesitaba (es posible que tenga que extender la matriz de codificaciones).

El script convierte el archivo codificado MIME nombres Recursivamente a través de la estructura de directorio especificada en UTF-8.

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

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

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

Debe ejecutarse tanto en CLI como a través de la web; Lo he probado en el navegador.

Haga copias de seguridad antes de ejecutar secuencias de comandos como esta 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;   
           }
       }


   }

1

Ya que está dispuesto a mudarse a Linux, puede instalar un servidor php en él y hacer un script bastante sencillo para volver a codificar los archivos. El grado de dificultad depende de si alguna vez has hecho alguna programación. Puede hacer referencia a estas funciones en php.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)

?>

Saludos, en realidad soy un programador de PHP y seguiré esa ruta. Sin embargo, descodificar los caracteres es más complicado que simplemente hacer un mb_convert_encoding en ellos: tomará algo como mb_decode_mimeheader, aún trabajando para entender cómo funciona esto. Publicaré la solución como respuesta cuando termine.
Pekka 웃

No se puede votar solo porque uno no necesita Linux ni un "servidor PHP" para ejecutar scripts PHP
grawity

@Pekka - No estoy lo suficientemente alto como para publicar un comentario en su respuesta publicada. ¿Has probado iconv () con la opción TRANSLIT para corregir los caracteres que no están codificando correctamente? $ output = iconv ("ISO-8859-1", "UTF-8 // TRANSLIT", $ input); Podría funcionar
JMC

@grawity - Nunca ejecuté scripts php sin un servidor php, ¿cómo lo haces? Intenté buscar en Google, pero no se me ocurrió nada en los primeros resultados. Mencioné linux porque dijo que estaba dispuesto a seguirlo en su pregunta y apache + php es fácil de instalar en la mayoría de las distribuciones de linux.
JMC

@JMC el problema son codificaciones confusas que comenzaron mucho antes que el proceso de exportación. Por lo tanto, es imposible saber cuál es la codificación de inicio; puede usar mb_detect_encoding Pero no es 100% confiable. Ese sería el siguiente paso para el guión si alguien quiere llevarlo más lejos. Estoy contento con la forma en que hace las cosas ahora.
Pekka 웃
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.