로컬 NTFS 파티션에서 Windows의 불법 파일 이름을 방지하기 위한 iconv 모듈(rsync와 함께 사용)

로컬 NTFS 파티션에서 Windows의 불법 파일 이름을 방지하기 위한 iconv 모듈(rsync와 함께 사용)

NTFS 볼륨을 내 Unix(Ubuntu) 시스템에 로컬로 연결하고 rsync를 사용하여 Windows에서 결과를 읽을 수 있도록 일부 Unix 디렉터리를 여기에 복사하고 싶습니다.

나는 소유권과 권한에 관심이 없습니다. 수정일자를 보존할 수 있으면 좋을 것 같습니다. 디렉토리와 파일만 필요합니다(기호 링크도 괜찮지만 복사할 수 없는 경우에는 문제가 되지 않습니다).

두 가지 명백한 문제는 대소문자 구분 및 Windows 파일 이름의 잘못된 문자입니다. 예를 들어, Linux에서는 "a"와 "A"라는 두 개의 파일을 NTFS 볼륨에 복사할 수 있지만 Windows에서는 그 중 최대 하나에 액세스할 수 있습니다. 그러나 나는 그 문제를 무시하게 되어 기쁘다. 내가 관심 있는 것은 Windows 파일 이름에 있는 불법 문자입니다. <, >, :, ", /, \, |, ? 및 *(실제로는 ASCII 0-31도 있지만 신경 쓰지 않습니다. "."로 끝나는 파일에도 문제가 있을 수 있나요?

rsync가 자동으로 "a:"라는 파일의 이름을 a(COLON)로 바꾸고 합법적인 이름으로 끝나도록 하고 싶습니다(이상적으로는 a(COLON)를 다시 a:로 번역)

Windows에서 금지된 문자를 피하기 위해 rsync가 자동으로 파일 이름을 바꿀 수 있습니까?

  • 내가 아는 한 rsync를 사용할 수 있습니다이러한 작업을 수행하기 위해 Windows 파일 이름에 대한 표준 iconv 모듈이 있습니까? (직접 gconv 모듈을 프로그래밍하는 방법을 간략히 살펴봤지만 C 지식이 부족하여 너무 복잡해 보였습니다.)
  • 나는 들었다rdiff 백업유사한 변환을 수행하는 것이 가능하지만 홈 페이지에는 "자동으로" 작업을 수행한다고 언급되어 있으며 로컬에 설치된 NTFS 볼륨이 신뢰할 수 있는 방식으로 이름 바꾸기를 트리거하는지 확실하지 않습니다.
  • 나는 거기에 있다는 것을 안다퓨즈 포시소블, 그러나 이것은 내 목적에 비해 약간 과잉인 것 같고 잘 문서화되지 않은 것 같습니다(어떤 문자가 어떤 방식으로 번역됩니까? 모든 파일 이름이 8.3 또는 다른 것으로 잘리나요? 소유자/첨부 파일을 가져오는 것을 피할 수 있습니까? 권한 정보 , 이 정보는 필요하지 않습니다.)
  • 예를 들어 다음을 사용하여 이 작업을 수행할 수 있다는 것을 알고 있습니다.아스팔트파일; 하지만 그건 내가 원하는 것이 아닙니다. (구체적으로는 NTFS 볼륨에서 Windows의 다른 백업 파티션으로 추가로 복사하여 변경된 파일만 복사하고 싶습니다.)
  • 알아요"창 이름" 옵션을 사용하면 문제가 있는 파일의 이름을 바꾸는 대신 문제가 있는 파일이 생성되는 것을 방지할 수 있습니다.

고쳐 쓰다:제 질문이 그다지 명확하지 않은 것 같습니다. 좀 더 명확한 예를 들어 보겠습니다. 예를 들어 WINDOWS-1251은 저에게 적합하지 않았습니다. iconv -f utf-8 -t WINDOWS-1251//TRANSLIT 변화

123 abc ABC äö &:<!|

입력하다

123 abc ABC ao &:<!|

문자열을 다음과 같은 것으로 변환하는 windows-filenams(존재하지 않음)와 같은 코드 페이지가 필요합니다.

123 abc ABC äö &(COLON)(LT)!(PIPE)

업데이트 2:나는 지금 포기하고 문제가 되는 파일의 이름을 "수동으로"(즉, 스크립트를 통해) 바꿨습니다. 이제부터 모든 rsync 실행 전에 문제가 되는 파일 이름을 확인하는 스크립트를 실행합니다(그러나 이름 바꾸기는 자동으로 처리하지 않습니다).

# find stuff containing forbidden chars
find $MYDIR -regex '.*/[^/]*[<>:*"\\|?][^/]*'
# find stuff containing dot as last character (supposedly bad for windows)
find $MYDIR -regex '.*\.'
# find stuff that is identical case insensitive
find $MYDIR -print0 | sort -z | uniq -diz | tr '\0' '\n'

(마지막 줄은중복된 파일 이름에 대해 대소문자를 구분하지 않고 검색)

답변1

실용적인 해결책은 원본 파일에 대한 하드 링크를 사용하여 원하는 변환된 파일 이름으로 소스 디렉터리를 로컬에서 재생산한 다음 이 복사본을 있는 그대로 ntfs 파일 시스템에 rsync하는 것입니다.

예를 들어, 이 Perl 스크립트는 계층 구조를 원치 않는 문자로 복사 하고 /tmp/a/원치 않는 문자를 URL 인코딩(2개의 16진수 사용)하여 해당 문자가/tmp/b/ (하드 링크) 되고 디렉토리가 디렉토리가 되도록 하는 방법을 보여줍니다.%file:bfile%3ab%b<ha>%25b%3cha%3e

#!/usr/bin/perl
use strict;
use File::Find;
my $startdir = '/tmp/a';
my $copydir = '/tmp/b';
sub handlefile{
    my $name = substr($File::Find::name,1);
    my $oldname = $startdir.$name;
    $name =~ s/([;, \t+%&<>:\"\\|?*])/sprintf('%%%02x',ord($1))/ge;
    $name = $copydir.$name;
    printf "from %s to %s\n",$oldname,$name;
    if(!-l and -d){ mkdir($name) or die $!; }
    else{ link($oldname,$name) or die $!; }
}
chdir($startdir) or die;
find(\&handlefile, '.');

rsync /tmp/b그런 다음 ntfs로 이동할 수 있습니다 . 이것은 단지 데모일 뿐이며 유니코드 및 ntfs의 다른 제한 사항(예: 최대 파일 이름 길이)을 해결해야 합니다. 소문자/대문자 충돌을 확인하고 원하는 인코딩( :to COLON등)을 사용할 수도 있습니다. 두 번째 단계를 수행하여 디렉터리의 타임스탬프를 수정할 수 있습니다. 수백만 개의 파일이 있지 않는 한, 파일에 대한 하드 링크가 포함된 디렉터리 구조의 복사본을 만드는 데 필요한 작업은 그다지 번거롭지 않습니다.

관련 정보