
나는 해산한 IMAP 계정에서 저장된 이메일 폴더를 가지고 있습니다.
파일 이름은 각 이메일의 제목입니다.
안타깝게도 비ASCII 인코딩을 사용하면 제목 줄이 내부적으로 보이는 것처럼 보입니다. 접두어가 붙고 =_
인코딩이 사용됩니다.
=_UTF-8_Q_Auftragsbest=C3=A4tigung_(Kundennummer__)_=_20100819_150312_37.eml
=_windows-1252_Q_Best=E4tigung=3A_Wir_haben_Ihre_=_20100819_150310_28.eml
파일 시스템 수준에서 이 문제를 대량으로 수정하는 데 사용할 수 있는 도구를 아는 사람이 있습니까?
해결 방법은 1. =_ENCODING
접두사를 제거하고 2. 가능하다면 파일 이름의 인코딩된 문자를 적절한 파일 시스템에 해당하는 Umlaut로 변환해야 합니다.
저는 Windows 7 또는 XP를 사용하고 있지만 Linux VM으로 가져갈 준비가 되어 있습니다.큰폴더와 자동화된 솔루션은엄청난.
답변1
나는 PHP 스크립트를 직접 만들었습니다. 다른 사람이 비슷한 문제를 겪을 경우를 대비해 공유하고 싶다고 생각했습니다. 그것은 나와 내가 필요한 인코딩에 적합합니다(인코딩 배열을 확장해야 할 수도 있습니다).
스크립트는 MIME 인코딩된 파일을 변환합니다.이름지정된 디렉토리 구조 전체를 UTF-8로 반복적으로 변환합니다.
완전히 완벽한 결과를 생성하지는 않습니다. 이중으로 변환되거나 전혀 변환되지 않는 특수 문자가 여러 개 있습니다. 제가 아는 한, 이는 IMAP 내보내기의 결함이거나 이메일 자체 내부의 잘못된 인코딩 정보입니다.
mb_decode_mimeheader()
모든 것의 핵심이다.
공개 도메인으로 출시되었습니다. 어떠한 보증도 없습니다. PHP 5.2가 필요합니다.
CLI와 웹을 통해 모두 실행되어야 합니다. 브라우저에서 테스트해봤습니다.
데이터에 이와 같은 스크립트를 실행하기 전에 백업을 만드십시오.
<?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;
}
}
}
답변2
Linux로 이동할 의향이 있으므로 Linux에 PHP 서버를 설치하고 파일을 다시 인코딩하는 매우 쉬운 스크립트를 만들 수 있습니다. 난이도는 프로그래밍을 해본 적이 있는지에 따라 다릅니다. 이러한 기능은 다음에서 참조할 수 있습니다.php.net
꼭 필요한 기능들입니다
<?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)
?>